aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp50
1 files changed, 33 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 24f7d27..ae40895 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3352,6 +3352,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
case Decl::VarTemplateSpecialization:
case Decl::VarTemplatePartialSpecialization:
case Decl::Decomposition:
+ case Decl::Binding:
case Decl::OMPCapturedExpr:
// In C, "extern void blah;" is valid and is an r-value.
if (!getLangOpts().CPlusPlus && !type.hasQualifiers() &&
@@ -3371,20 +3372,13 @@ ExprResult Sema::BuildDeclarationNameExpr(
// potentially-evaluated contexts? Since the variable isn't actually
// captured in an unevaluated context, it seems that the answer is no.
if (!isUnevaluatedContext()) {
- QualType CapturedType = getCapturedDeclRefType(cast<VarDecl>(VD), Loc);
+ QualType CapturedType = getCapturedDeclRefType(cast<ValueDecl>(VD), Loc);
if (!CapturedType.isNull())
type = CapturedType;
}
-
break;
}
- case Decl::Binding:
- // These are always lvalues.
- valueKind = VK_LValue;
- type = type.getNonReferenceType();
- break;
-
case Decl::Function: {
if (unsigned BID = cast<FunctionDecl>(VD)->getBuiltinID()) {
if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
@@ -13297,11 +13291,24 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
if (!DRE) return NCCK_None;
if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;
- // The declaration must be a variable which is not declared 'const'.
- VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
- if (!var) return NCCK_None;
- if (var->getType().isConstQualified()) return NCCK_None;
- assert(var->hasLocalStorage() && "capture added 'const' to non-local?");
+ ValueDecl *Value = dyn_cast<ValueDecl>(DRE->getDecl());
+
+ // The declaration must be a value which is not declared 'const'.
+ if (!Value || Value->getType().isConstQualified())
+ return NCCK_None;
+
+ BindingDecl *Binding = dyn_cast<BindingDecl>(Value);
+ if (Binding) {
+ assert(S.getLangOpts().CPlusPlus && "BindingDecl outside of C++?");
+ assert(!isa<BlockDecl>(Binding->getDeclContext()));
+ return NCCK_Lambda;
+ }
+
+ VarDecl *Var = dyn_cast<VarDecl>(Value);
+ if (!Var)
+ return NCCK_None;
+
+ assert(Var->hasLocalStorage() && "capture added 'const' to non-local?");
// Decide whether the first capture was for a block or a lambda.
DeclContext *DC = S.CurContext, *Prev = nullptr;
@@ -13310,16 +13317,16 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
// For init-capture, it is possible that the variable belongs to the
// template pattern of the current context.
if (auto *FD = dyn_cast<FunctionDecl>(DC))
- if (var->isInitCapture() &&
- FD->getTemplateInstantiationPattern() == var->getDeclContext())
+ if (Var->isInitCapture() &&
+ FD->getTemplateInstantiationPattern() == Var->getDeclContext())
break;
- if (DC == var->getDeclContext())
+ if (DC == Var->getDeclContext())
break;
Prev = DC;
DC = DC->getParent();
}
// Unless we have an init-capture, we've gone one step too far.
- if (!var->isInitCapture())
+ if (!Var->isInitCapture())
DC = Prev;
return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda);
}
@@ -16585,6 +16592,13 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
<< TInfo->getTypeLoc().getSourceRange();
}
+ if (TInfo->getType()->isArrayType()) {
+ DiagRuntimeBehavior(TInfo->getTypeLoc().getBeginLoc(), E,
+ PDiag(diag::warn_second_parameter_to_va_arg_array)
+ << TInfo->getType()
+ << TInfo->getTypeLoc().getSourceRange());
+ }
+
// Check for va_arg where arguments of the given type will be promoted
// (i.e. this va_arg is guaranteed to have undefined behavior).
QualType PromoteType;
@@ -19247,6 +19261,8 @@ bool Sema::NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc) {
}
QualType Sema::getCapturedDeclRefType(ValueDecl *Var, SourceLocation Loc) {
+ assert(Var && "Null value cannot be captured");
+
QualType CaptureType;
QualType DeclRefType;