summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-01-21 12:54:48 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-01-21 12:54:48 +0000
commit93a546a326d679d53ae7314e73bf72b43209d683 (patch)
treea18be0ed40978f1e16216e4c232eb22cfa6f0a1b /clang/lib/Sema/SemaExpr.cpp
parent14f9535eecf83a36e275a5f22c51d12febf43c02 (diff)
downloadbcm5719-llvm-93a546a326d679d53ae7314e73bf72b43209d683.tar.gz
bcm5719-llvm-93a546a326d679d53ae7314e73bf72b43209d683.zip
Fix crash for typedefs for arrays of runtime bounds in Lambdas/Captured Statements, used in sizeof() expression only.
llvm-svn: 258396
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp251
1 files changed, 137 insertions, 114 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index aacbda402f7..fc1a9268b16 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3748,6 +3748,128 @@ bool Sema::CheckVecStepExpr(Expr *E) {
return CheckUnaryExprOrTypeTraitOperand(E, UETT_VecStep);
}
+static void captureVariablyModifiedType(ASTContext &Context, QualType T,
+ CapturingScopeInfo *CSI) {
+ assert(T->isVariablyModifiedType());
+ assert(CSI != nullptr);
+
+ // We're going to walk down into the type and look for VLA expressions.
+ do {
+ const Type *Ty = T.getTypePtr();
+ switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+ T = QualType();
+ break;
+ // These types are never variably-modified.
+ case Type::Builtin:
+ case Type::Complex:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::Record:
+ case Type::Enum:
+ case Type::Elaborated:
+ case Type::TemplateSpecialization:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ case Type::ObjCObjectPointer:
+ case Type::Pipe:
+ llvm_unreachable("type class is never variably-modified!");
+ case Type::Adjusted:
+ T = cast<AdjustedType>(Ty)->getOriginalType();
+ break;
+ case Type::Decayed:
+ T = cast<DecayedType>(Ty)->getPointeeType();
+ break;
+ case Type::Pointer:
+ T = cast<PointerType>(Ty)->getPointeeType();
+ break;
+ case Type::BlockPointer:
+ T = cast<BlockPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::LValueReference:
+ case Type::RValueReference:
+ T = cast<ReferenceType>(Ty)->getPointeeType();
+ break;
+ case Type::MemberPointer:
+ T = cast<MemberPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // Losing element qualification here is fine.
+ T = cast<ArrayType>(Ty)->getElementType();
+ break;
+ case Type::VariableArray: {
+ // Losing element qualification here is fine.
+ const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (auto Size = VAT->getSizeExpr()) {
+ if (!CSI->isVLATypeCaptured(VAT)) {
+ RecordDecl *CapRecord = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+ CapRecord = LSI->Lambda;
+ } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+ CapRecord = CRSI->TheRecordDecl;
+ }
+ if (CapRecord) {
+ auto ExprLoc = Size->getExprLoc();
+ auto SizeType = Context.getSizeType();
+ // Build the non-static data member.
+ auto Field =
+ FieldDecl::Create(Context, CapRecord, ExprLoc, ExprLoc,
+ /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
+ /*BW*/ nullptr, /*Mutable*/ false,
+ /*InitStyle*/ ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Field->setCapturedVLAType(VAT);
+ CapRecord->addDecl(Field);
+
+ CSI->addVLATypeCapture(ExprLoc, SizeType);
+ }
+ }
+ }
+ T = VAT->getElementType();
+ break;
+ }
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ T = cast<FunctionType>(Ty)->getReturnType();
+ break;
+ case Type::Paren:
+ case Type::TypeOf:
+ case Type::UnaryTransform:
+ case Type::Attributed:
+ case Type::SubstTemplateTypeParm:
+ case Type::PackExpansion:
+ // Keep walking after single level desugaring.
+ T = T.getSingleStepDesugaredType(Context);
+ break;
+ case Type::Typedef:
+ T = cast<TypedefType>(Ty)->desugar();
+ break;
+ case Type::Decltype:
+ T = cast<DecltypeType>(Ty)->desugar();
+ break;
+ case Type::Auto:
+ T = cast<AutoType>(Ty)->getDeducedType();
+ break;
+ case Type::TypeOfExpr:
+ T = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+ break;
+ case Type::Atomic:
+ T = cast<AtomicType>(Ty)->getValueType();
+ break;
+ }
+ } while (!T.isNull() && T->isVariablyModifiedType());
+}
+
/// \brief Build a sizeof or alignof expression given a type operand.
ExprResult
Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
@@ -3763,6 +3885,20 @@ Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
CheckUnaryExprOrTypeTraitOperand(T, OpLoc, R, ExprKind))
return ExprError();
+ if (T->isVariablyModifiedType() && FunctionScopes.size() > 1) {
+ if (auto *TT = T->getAs<TypedefType>()) {
+ if (auto *CSI = dyn_cast<CapturingScopeInfo>(FunctionScopes.back())) {
+ DeclContext *DC = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI))
+ DC = LSI->CallOperator;
+ else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI))
+ DC = CRSI->TheCapturedDecl;
+ if (DC && TT->getDecl()->getDeclContext() != DC)
+ captureVariablyModifiedType(Context, T, CSI);
+ }
+ }
+ }
+
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
@@ -13158,120 +13294,7 @@ bool Sema::tryCaptureVariable(
QualType QTy = Var->getType();
if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
QTy = PVD->getOriginalType();
- do {
- const Type *Ty = QTy.getTypePtr();
- switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- QTy = QualType();
- break;
- // These types are never variably-modified.
- case Type::Builtin:
- case Type::Complex:
- case Type::Vector:
- case Type::ExtVector:
- case Type::Record:
- case Type::Enum:
- case Type::Elaborated:
- case Type::TemplateSpecialization:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::ObjCObjectPointer:
- case Type::Pipe:
- llvm_unreachable("type class is never variably-modified!");
- case Type::Adjusted:
- QTy = cast<AdjustedType>(Ty)->getOriginalType();
- break;
- case Type::Decayed:
- QTy = cast<DecayedType>(Ty)->getPointeeType();
- break;
- case Type::Pointer:
- QTy = cast<PointerType>(Ty)->getPointeeType();
- break;
- case Type::BlockPointer:
- QTy = cast<BlockPointerType>(Ty)->getPointeeType();
- break;
- case Type::LValueReference:
- case Type::RValueReference:
- QTy = cast<ReferenceType>(Ty)->getPointeeType();
- break;
- case Type::MemberPointer:
- QTy = cast<MemberPointerType>(Ty)->getPointeeType();
- break;
- case Type::ConstantArray:
- case Type::IncompleteArray:
- // Losing element qualification here is fine.
- QTy = cast<ArrayType>(Ty)->getElementType();
- break;
- case Type::VariableArray: {
- // Losing element qualification here is fine.
- const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
-
- // Unknown size indication requires no size computation.
- // Otherwise, evaluate and record it.
- if (auto Size = VAT->getSizeExpr()) {
- if (!CSI->isVLATypeCaptured(VAT)) {
- RecordDecl *CapRecord = nullptr;
- if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
- CapRecord = LSI->Lambda;
- } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
- CapRecord = CRSI->TheRecordDecl;
- }
- if (CapRecord) {
- auto ExprLoc = Size->getExprLoc();
- auto SizeType = Context.getSizeType();
- // Build the non-static data member.
- auto Field = FieldDecl::Create(
- Context, CapRecord, ExprLoc, ExprLoc,
- /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
- /*BW*/ nullptr, /*Mutable*/ false,
- /*InitStyle*/ ICIS_NoInit);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
- Field->setCapturedVLAType(VAT);
- CapRecord->addDecl(Field);
-
- CSI->addVLATypeCapture(ExprLoc, SizeType);
- }
- }
- }
- QTy = VAT->getElementType();
- break;
- }
- case Type::FunctionProto:
- case Type::FunctionNoProto:
- QTy = cast<FunctionType>(Ty)->getReturnType();
- break;
- case Type::Paren:
- case Type::TypeOf:
- case Type::UnaryTransform:
- case Type::Attributed:
- case Type::SubstTemplateTypeParm:
- case Type::PackExpansion:
- // Keep walking after single level desugaring.
- QTy = QTy.getSingleStepDesugaredType(getASTContext());
- break;
- case Type::Typedef:
- QTy = cast<TypedefType>(Ty)->desugar();
- break;
- case Type::Decltype:
- QTy = cast<DecltypeType>(Ty)->desugar();
- break;
- case Type::Auto:
- QTy = cast<AutoType>(Ty)->getDeducedType();
- break;
- case Type::TypeOfExpr:
- QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
- break;
- case Type::Atomic:
- QTy = cast<AtomicType>(Ty)->getValueType();
- break;
- }
- } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+ captureVariablyModifiedType(Context, QTy, CSI);
}
if (getLangOpts().OpenMP) {
OpenPOWER on IntegriCloud