aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp2
-rw-r--r--clang/lib/Sema/CMakeLists.txt1
-rw-r--r--clang/lib/Sema/CheckExprLifetime.cpp2
-rw-r--r--clang/lib/Sema/SemaAPINotes.cpp2
-rw-r--r--clang/lib/Sema/SemaConcept.cpp27
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp169
6 files changed, 24 insertions, 179 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index e9ca8ce..9abaf79 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -29,7 +29,7 @@
#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
#include "clang/Analysis/Analyses/CalledOnceCheck.h"
#include "clang/Analysis/Analyses/Consumed.h"
-#include "clang/Analysis/Analyses/LifetimeSafety.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h"
#include "clang/Analysis/Analyses/ReachableCode.h"
#include "clang/Analysis/Analyses/ThreadSafety.h"
#include "clang/Analysis/Analyses/UninitializedValues.h"
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 51e0ee1..0ebf56e 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -111,6 +111,7 @@ add_clang_library(clangSema
clangAPINotes
clangAST
clangAnalysis
+ clangAnalysisLifetimeSafety
clangBasic
clangEdit
clangLex
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index e8a7ad3..8aebf53 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -10,7 +10,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
-#include "clang/Analysis/Analyses/LifetimeAnnotations.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Sema.h"
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index 35cdfbf..0d8d0fa 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -17,7 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Analysis/Analyses/LifetimeAnnotations.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Lexer.h"
#include "clang/Sema/SemaObjC.h"
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index f4df63c..9cbd1bd 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -604,6 +604,10 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
return std::nullopt;
const NormalizedConstraint::OccurenceList &Used =
Constraint.mappingOccurenceList();
+ // The empty MLTAL situation should only occur when evaluating non-dependent
+ // constraints.
+ if (!MLTAL.getNumSubstitutedLevels())
+ MLTAL.addOuterTemplateArguments(TD, {}, /*Final=*/false);
SubstitutedOuterMost =
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
unsigned Offset = 0;
@@ -623,9 +627,7 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
if (Offset < SubstitutedOuterMost.size())
SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset);
- MLTAL.replaceOutermostTemplateArguments(
- const_cast<NamedDecl *>(Constraint.getConstraintDecl()),
- SubstitutedOuterMost);
+ MLTAL.replaceOutermostTemplateArguments(TD, SubstitutedOuterMost);
return std::move(MLTAL);
}
@@ -956,11 +958,20 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
? Constraint.getPackSubstitutionIndex()
: PackSubstitutionIndex;
- Sema::InstantiatingTemplate _(S, ConceptId->getBeginLoc(),
- Sema::InstantiatingTemplate::ConstraintsCheck{},
- ConceptId->getNamedConcept(),
- MLTAL.getInnermost(),
- Constraint.getSourceRange());
+ Sema::InstantiatingTemplate InstTemplate(
+ S, ConceptId->getBeginLoc(),
+ Sema::InstantiatingTemplate::ConstraintsCheck{},
+ ConceptId->getNamedConcept(),
+ // We may have empty template arguments when checking non-dependent
+ // nested constraint expressions.
+ // In such cases, non-SFINAE errors would have already been diagnosed
+ // during parameter mapping substitution, so the instantiating template
+ // arguments are less useful here.
+ MLTAL.getNumSubstitutedLevels() ? MLTAL.getInnermost()
+ : ArrayRef<TemplateArgument>{},
+ Constraint.getSourceRange());
+ if (InstTemplate.isInvalid())
+ return ExprError();
unsigned Size = Satisfaction.Details.size();
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 779b6e9..f3969a9 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2898,15 +2898,6 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()))
VarTy = ASE->getElementType();
- llvm::SmallVector<OpenACCReductionRecipe::CombinerRecipe, 1> CombinerRecipes;
-
- // We use the 'set-ness' of the alloca-decl to determine whether the combiner
- // is 'set' or not, so we can skip any attempts at it if we're going to fail
- // at any of the combiners.
- if (CreateReductionCombinerRecipe(VarExpr->getBeginLoc(), ReductionOperator,
- VarTy, CombinerRecipes))
- return OpenACCReductionRecipe::Empty();
-
VarDecl *AllocaDecl = CreateAllocaDecl(
getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),
&getASTContext().Idents.get("openacc.reduction.init"), VarTy);
@@ -2955,163 +2946,5 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
AllocaDecl->setInit(Init.get());
AllocaDecl->setInitStyle(VarDecl::CallInit);
}
-
- return OpenACCReductionRecipe(AllocaDecl, CombinerRecipes);
-}
-
-bool SemaOpenACC::CreateReductionCombinerRecipe(
- SourceLocation Loc, OpenACCReductionOperator ReductionOperator,
- QualType VarTy,
- llvm::SmallVectorImpl<OpenACCReductionRecipe::CombinerRecipe>
- &CombinerRecipes) {
- // Now we can try to generate the 'combiner' recipe. This is a little
- // complicated in that if the 'VarTy' is an array type, we want to take its
- // element type so we can generate that. Additionally, if this is a struct,
- // we have two options: If there is overloaded operators, we want to take
- // THOSE, else we want to do the individual elements.
-
- BinaryOperatorKind BinOp;
- switch (ReductionOperator) {
- case OpenACCReductionOperator::Invalid:
- // This can only happen when there is an error, and since these inits
- // are used for code generation, we can just ignore/not bother doing any
- // initialization here.
- CombinerRecipes.push_back({nullptr, nullptr, nullptr});
- return false;
- case OpenACCReductionOperator::Addition:
- BinOp = BinaryOperatorKind::BO_AddAssign;
- break;
- case OpenACCReductionOperator::Multiplication:
- BinOp = BinaryOperatorKind::BO_MulAssign;
- break;
- case OpenACCReductionOperator::BitwiseAnd:
- BinOp = BinaryOperatorKind::BO_AndAssign;
- break;
- case OpenACCReductionOperator::BitwiseOr:
- BinOp = BinaryOperatorKind::BO_OrAssign;
- break;
- case OpenACCReductionOperator::BitwiseXOr:
- BinOp = BinaryOperatorKind::BO_XorAssign;
- break;
-
- case OpenACCReductionOperator::Max:
- case OpenACCReductionOperator::Min:
- case OpenACCReductionOperator::And:
- case OpenACCReductionOperator::Or:
- // We just want a 'NYI' error in the backend, so leave an empty combiner
- // recipe, and claim success.
- CombinerRecipes.push_back({nullptr, nullptr, nullptr});
- return false;
- }
-
- // If VarTy is an array type, at the top level only, we want to do our
- // compares/decomp/etc at the element level.
- if (auto *AT = getASTContext().getAsArrayType(VarTy))
- VarTy = AT->getElementType();
-
- assert(!VarTy->isArrayType() && "Only 1 level of array allowed");
-
- auto tryCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
- bool IncludeTrap) {
- // TODO: OpenACC: we have to figure out based on the bin-op how to do the
- // ones that we can't just use compound operators for. So &&, ||, max, and
- // min aren't really clear what we could do here.
- if (IncludeTrap) {
- // Trap all of the errors here, we'll emit our own at the end.
- Sema::TentativeAnalysisScope Trap{SemaRef};
-
- return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE,
- RHSDRE,
- /*ForFoldExpr=*/false);
- } else {
- return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE,
- RHSDRE,
- /*ForFoldExpr=*/false);
- }
- };
-
- struct CombinerAttemptTy {
- VarDecl *LHS;
- DeclRefExpr *LHSDRE;
- VarDecl *RHS;
- DeclRefExpr *RHSDRE;
- Expr *Op;
- };
-
- auto formCombiner = [&, this](QualType Ty) -> CombinerAttemptTy {
- VarDecl *LHSDecl = CreateAllocaDecl(
- getASTContext(), SemaRef.getCurContext(), Loc,
- &getASTContext().Idents.get("openacc.reduction.combiner.lhs"), Ty);
- auto *LHSDRE = DeclRefExpr::Create(
- getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
- /*ReferstoEnclosingVariableOrCapture=*/false,
- DeclarationNameInfo{DeclarationName{LHSDecl->getDeclName()},
- LHSDecl->getBeginLoc()},
- Ty, clang::VK_LValue, LHSDecl, nullptr, NOUR_None);
- VarDecl *RHSDecl = CreateAllocaDecl(
- getASTContext(), SemaRef.getCurContext(), Loc,
- &getASTContext().Idents.get("openacc.reduction.combiner.lhs"), Ty);
- auto *RHSDRE = DeclRefExpr::Create(
- getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
- /*ReferstoEnclosingVariableOrCapture=*/false,
- DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
- RHSDecl->getBeginLoc()},
- Ty, clang::VK_LValue, RHSDecl, nullptr, NOUR_None);
-
- ExprResult BinOpResult = tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true);
-
- return {LHSDecl, LHSDRE, RHSDecl, RHSDRE, BinOpResult.get()};
- };
-
- CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
-
- if (TopLevelCombinerInfo.Op) {
- if (!TopLevelCombinerInfo.Op->containsErrors() &&
- TopLevelCombinerInfo.Op->isInstantiationDependent()) {
- // If this is instantiation dependent, we're just going to 'give up' here
- // and count on us to get it right during instantaition.
- CombinerRecipes.push_back({nullptr, nullptr, nullptr});
- return false;
- } else if (!TopLevelCombinerInfo.Op->containsErrors()) {
- // Else, we succeeded, we can just return this combiner.
- CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
- TopLevelCombinerInfo.RHS,
- TopLevelCombinerInfo.Op});
- return false;
- }
- }
-
- // Since the 'root' level didn't fail, the only thing that could be successful
- // is a struct that we decompose on its individual fields.
-
- RecordDecl *RD = VarTy->getAsRecordDecl();
- if (!RD) {
- Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
- tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
- /*IncludeTrap=*/false);
- return true;
- }
-
- for (const FieldDecl *FD : RD->fields()) {
- CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
-
- if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
- Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
- Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
- tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
- /*IncludeTrap=*/false);
- return true;
- }
-
- if (FieldCombinerInfo.Op->isInstantiationDependent()) {
- // If this is instantiation dependent, we're just going to 'give up' here
- // and count on us to get it right during instantaition.
- CombinerRecipes.push_back({nullptr, nullptr, nullptr});
- } else {
- CombinerRecipes.push_back(
- {FieldCombinerInfo.LHS, FieldCombinerInfo.RHS, FieldCombinerInfo.Op});
- }
- }
-
- return false;
+ return OpenACCReductionRecipe(AllocaDecl, {});
}