Author: void Date: Thu Nov 8 16:41:36 2018 New Revision: 346455 URL: http://llvm.org/viewvc/llvm-project?rev=346455&view=rev Log: Compound literals, enums, et al require const expr
Summary: Compound literals, enums, file-scoped arrays, etc. require their initializers and size specifiers to be constant. Wrap the initializer expressions in a ConstantExpr so that we can easily check for this later on. Reviewers: rsmith, shafik Reviewed By: rsmith Subscribers: cfe-commits, jyknight, nickdesaulniers Differential Revision: https://reviews.llvm.org/D53921 Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprAgg.cpp cfe/trunk/lib/CodeGen/CGExprComplex.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/test/Import/switch-stmt/test.cpp cfe/trunk/test/Misc/ast-dump-attr.cpp cfe/trunk/test/Misc/ast-dump-c-attr.c cfe/trunk/test/Misc/ast-dump-color.cpp cfe/trunk/test/Misc/ast-dump-decl.c cfe/trunk/test/Misc/ast-dump-decl.cpp cfe/trunk/test/SemaCXX/compound-literal.cpp cfe/trunk/test/Tooling/clang-check-ast-dump.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Thu Nov 8 16:41:36 2018 @@ -3024,8 +3024,7 @@ class ImplicitCastExpr final private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { - } + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { } /// Construct an empty implicit cast. explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize) @@ -3068,8 +3067,13 @@ public: inline Expr *Expr::IgnoreImpCasts() { Expr *e = this; - while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e)) - e = ice->getSubExpr(); + while (true) + if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e)) + e = ice->getSubExpr(); + else if (ConstantExpr *ce = dyn_cast<ConstantExpr>(e)) + e = ce->getSubExpr(); + else + break; return e; } Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Nov 8 16:41:36 2018 @@ -1574,6 +1574,18 @@ extern const internal::VariadicDynCastAl UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; +/// Matches a constant expression wrapper. +/// +/// Example matches the constant in the case statement: +/// (matcher = constantExpr()) +/// \code +/// switch (a) { +/// case 37: break; +/// } +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> + constantExpr; + /// Matches parentheses used in expressions. /// /// Example matches (foo() + 1) Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Nov 8 16:41:36 2018 @@ -579,6 +579,7 @@ namespace clang { ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E); ExpectedStmt VisitAtomicExpr(AtomicExpr *E); ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E); + ExpectedStmt VisitConstantExpr(ConstantExpr *E); ExpectedStmt VisitParenExpr(ParenExpr *E); ExpectedStmt VisitParenListExpr(ParenListExpr *E); ExpectedStmt VisitStmtExpr(StmtExpr *E); @@ -6366,6 +6367,17 @@ ExpectedStmt ASTNodeImporter::VisitAddrL ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType); } +ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) { + auto Imp = importSeq(E->getSubExpr()); + if (!Imp) + return Imp.takeError(); + + Expr *ToSubExpr; + std::tie(ToSubExpr) = *Imp; + + return new (Importer.getToContext()) ConstantExpr(ToSubExpr); +} + ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr()); if (!Imp) Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Thu Nov 8 16:41:36 2018 @@ -2585,6 +2585,10 @@ Expr *Expr::IgnoreParenCasts() { E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } @@ -2606,6 +2610,10 @@ Expr *Expr::IgnoreCasts() { E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } @@ -2631,6 +2639,9 @@ Expr *Expr::IgnoreParenLValueCasts() { = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) { E = NTTP->getReplacement(); continue; + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { + E = CE->getSubExpr(); + continue; } break; } @@ -2672,6 +2683,10 @@ Expr *Expr::IgnoreParenImpCasts() { E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Nov 8 16:41:36 2018 @@ -4719,6 +4719,8 @@ public: return Error(E); } + bool VisitConstantExpr(const ConstantExpr *E) + { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitParenExpr(const ParenExpr *E) { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitUnaryExtension(const UnaryOperator *E) Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original) +++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Thu Nov 8 16:41:36 2018 @@ -666,6 +666,7 @@ const internal::VariadicDynCastAllOfMatc unresolvedUsingValueDecl; const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; +const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr> cxxConstructExpr; Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original) +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Thu Nov 8 16:41:36 2018 @@ -153,6 +153,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(compoundStmt); REGISTER_MATCHER(conditionalOperator); REGISTER_MATCHER(constantArrayType); + REGISTER_MATCHER(constantExpr); REGISTER_MATCHER(containsDeclaration); REGISTER_MATCHER(continueStmt); REGISTER_MATCHER(cStyleCastExpr); Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Thu Nov 8 16:41:36 2018 @@ -551,6 +551,7 @@ private: CFGBlock *VisitGotoStmt(GotoStmt *G); CFGBlock *VisitIfStmt(IfStmt *I); CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc); + CFGBlock *VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc); CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I); CFGBlock *VisitLabelStmt(LabelStmt *L); CFGBlock *VisitBlockExpr(BlockExpr *E, AddStmtChoice asc); @@ -2100,6 +2101,9 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, Ad case Stmt::ImplicitCastExprClass: return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc); + case Stmt::ConstantExprClass: + return VisitConstantExpr(cast<ConstantExpr>(S), asc); + case Stmt::IndirectGotoStmtClass: return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S)); @@ -4380,6 +4384,10 @@ CFGBlock *CFGBuilder::VisitImplicitCastE return Visit(E->getSubExpr(), AddStmtChoice()); } +CFGBlock *CFGBuilder::VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc) { + return Visit(E->getSubExpr(), AddStmtChoice()); +} + CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { // Lazily create the indirect-goto dispatch block if there isn't one already. CFGBlock *IBlock = cfg->getIndirectGotoBlock(); @@ -4436,6 +4444,10 @@ tryAgain: E = cast<CXXFunctionalCastExpr>(E)->getSubExpr(); goto tryAgain; + case Stmt::ConstantExprClass: + E = cast<ConstantExpr>(E)->getSubExpr(); + goto tryAgain; + case Stmt::ParenExprClass: E = cast<ParenExpr>(E)->getSubExpr(); goto tryAgain; Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Nov 8 16:41:36 2018 @@ -1260,6 +1260,8 @@ LValue CodeGenFunction::EmitLValue(const return EmitVAArgExprLValue(cast<VAArgExpr>(E)); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E)); + case Expr::ConstantExprClass: + return EmitLValue(cast<ConstantExpr>(E)->getSubExpr()); case Expr::ParenExprClass: return EmitLValue(cast<ParenExpr>(E)->getSubExpr()); case Expr::GenericSelectionExprClass: Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Nov 8 16:41:36 2018 @@ -125,6 +125,10 @@ public: return Visit(E->getReplacement()); } + void VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } + // l-values. void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); } void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Thu Nov 8 16:41:36 2018 @@ -101,6 +101,9 @@ public: llvm_unreachable("Stmt can't have complex result type!"); } ComplexPairTy VisitExpr(Expr *S); + ComplexPairTy VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { return Visit(GE->getResultExpr()); Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Nov 8 16:41:36 2018 @@ -723,6 +723,10 @@ public: return nullptr; } + llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) { + return Visit(CE->getSubExpr(), T); + } + llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) { return Visit(PE->getSubExpr(), T); } @@ -1601,6 +1605,7 @@ private: ConstantLValue tryEmitBase(const APValue::LValueBase &base); ConstantLValue VisitStmt(const Stmt *S) { return nullptr; } + ConstantLValue VisitConstantExpr(const ConstantExpr *E); ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); ConstantLValue VisitStringLiteral(const StringLiteral *E); ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E); @@ -1756,6 +1761,11 @@ ConstantLValueEmitter::tryEmitBase(const } ConstantLValue +ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) { + return Visit(E->getSubExpr()); +} + +ConstantLValue ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E); } Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Nov 8 16:41:36 2018 @@ -398,6 +398,9 @@ public: } Value *VisitExpr(Expr *S); + Value *VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Nov 8 16:41:36 2018 @@ -5745,21 +5745,6 @@ Sema::BuildCompoundLiteralExpr(SourceLoc LiteralExpr = Result.get(); bool isFileScope = !CurContext->isFunctionOrMethod(); - if (isFileScope) { - if (!LiteralExpr->isTypeDependent() && - !LiteralExpr->isValueDependent() && - !literalType->isDependentType()) // C99 6.5.2.5p3 - if (CheckForConstantInitializer(LiteralExpr, literalType)) - return ExprError(); - } else if (literalType.getAddressSpace() != LangAS::opencl_private && - literalType.getAddressSpace() != LangAS::Default) { - // Embedded-C extensions to C99 6.5.2.5: - // "If the compound literal occurs inside the body of a function, the - // type name shall not be qualified by an address-space qualifier." - Diag(LParenLoc, diag::err_compound_literal_with_address_space) - << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); - return ExprError(); - } // In C, compound literals are l-values for some reason. // For GCC compatibility, in C++, file-scope array compound literals with @@ -5784,9 +5769,26 @@ Sema::BuildCompoundLiteralExpr(SourceLoc ? VK_RValue : VK_LValue; - return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope); + if (isFileScope) { + if (!LiteralExpr->isTypeDependent() && + !LiteralExpr->isValueDependent() && + !literalType->isDependentType()) // C99 6.5.2.5p3 + if (CheckForConstantInitializer(LiteralExpr, literalType)) + return ExprError(); + E = new (Context) ConstantExpr(E); + } else if (literalType.getAddressSpace() != LangAS::opencl_private && + literalType.getAddressSpace() != LangAS::Default) { + // Embedded-C extensions to C99 6.5.2.5: + // "If the compound literal occurs inside the body of a function, the + // type name shall not be qualified by an address-space qualifier." + Diag(LParenLoc, diag::err_compound_literal_with_address_space) + << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); + return ExprError(); + } + + return MaybeBindToTemporary(E); } ExprResult @@ -14144,7 +14146,7 @@ Sema::VerifyIntegerConstantExpression(Ex if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstIntCheckOverflow(Context); - return E; + return new (Context) ConstantExpr(E); } Expr::EvalResult EvalResult; @@ -14162,7 +14164,7 @@ Sema::VerifyIntegerConstantExpression(Ex if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } // If our only note is the usual "invalid subexpression" note, just point @@ -14190,7 +14192,7 @@ Sema::VerifyIntegerConstantExpression(Ex if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } namespace { @@ -16634,4 +16636,4 @@ ExprResult Sema::ActOnObjCAvailabilityCh return new (Context) ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy); -} \ No newline at end of file +} Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Nov 8 16:41:36 2018 @@ -5527,7 +5527,8 @@ void InitializationSequence::InitializeF // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. if (!S.getLangOpts().CPlusPlus && Initializer && - isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) && + (isa<ConstantExpr>(Initializer->IgnoreParens()) || + isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) && Initializer->getType()->isArrayType()) { const ArrayType *SourceAT = Context.getAsArrayType(Initializer->getType()); Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Nov 8 16:41:36 2018 @@ -5444,7 +5444,7 @@ static ExprResult CheckConvertedConstant if (Notes.empty()) { // It's a constant expression. - return Result; + return new (S.Context) ConstantExpr(Result.get()); } } Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Thu Nov 8 16:41:36 2018 @@ -2233,6 +2233,10 @@ QualType Sema::BuildArrayType(QualType T T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } + if (ArraySize && !CurContext->isFunctionOrMethod()) + // A file-scoped array must have a constant array size. + ArraySize = new (Context) ConstantExpr(ArraySize); + // OpenCL v1.2 s6.9.d: variable length arrays are not supported. if (getLangOpts().OpenCL && T->isVariableArrayType()) { Diag(Loc, diag::err_opencl_vla); Modified: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp Thu Nov 8 16:41:36 2018 @@ -92,6 +92,7 @@ SVal Environment::getSVal(const Environm case Stmt::ExprWithCleanupsClass: case Stmt::GenericSelectionExprClass: case Stmt::OpaqueValueExprClass: + case Stmt::ConstantExprClass: case Stmt::ParenExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: llvm_unreachable("Should have been handled by ignoreTransparentExprs"); Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Nov 8 16:41:36 2018 @@ -1267,9 +1267,6 @@ void ExprEngine::Visit(const Stmt *S, Ex case Stmt::ObjCPropertyRefExprClass: llvm_unreachable("These are handled by PseudoObjectExpr"); - case Expr::ConstantExprClass: - return Visit(cast<ConstantExpr>(S)->getSubExpr(), Pred, DstTop); - case Stmt::GNUNullExprClass: { // GNU __null is a pointer-width integer, not an actual pointer. ProgramStateRef state = Pred->getState(); @@ -1285,6 +1282,10 @@ void ExprEngine::Visit(const Stmt *S, Ex Bldr.addNodes(Dst); break; + case Expr::ConstantExprClass: + // Handled due to it being a wrapper class. + break; + case Stmt::ExprWithCleanupsClass: // Handled due to fully linearised CFG. break; Modified: cfe/trunk/test/Import/switch-stmt/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Import/switch-stmt/test.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Import/switch-stmt/test.cpp (original) +++ cfe/trunk/test/Import/switch-stmt/test.cpp Thu Nov 8 16:41:36 2018 @@ -4,15 +4,21 @@ // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt @@ -23,13 +29,17 @@ // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt Modified: cfe/trunk/test/Misc/ast-dump-attr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-attr.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Misc/ast-dump-attr.cpp (original) +++ cfe/trunk/test/Misc/ast-dump-attr.cpp Thu Nov 8 16:41:36 2018 @@ -35,7 +35,8 @@ int TestAlignedNull __attribute__((align int TestAlignedExpr __attribute__((aligned(4))); // CHECK: VarDecl{{.*}}TestAlignedExpr // CHECK-NEXT: AlignedAttr {{.*}} aligned -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral int TestEnum __attribute__((visibility("default"))); // CHECK: VarDecl{{.*}}TestEnum Modified: cfe/trunk/test/Misc/ast-dump-c-attr.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-c-attr.c?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Misc/ast-dump-c-attr.c (original) +++ cfe/trunk/test/Misc/ast-dump-c-attr.c Thu Nov 8 16:41:36 2018 @@ -23,7 +23,8 @@ struct [[deprecated]] Test4 { // CHECK-NEXT: FieldDecl{{.*}}Test6 // CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" "" // CHECK-NEXT: FieldDecl{{.*}}Test7 -// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12 +// CHECK-NEXT: Constant{{.*}}'int' +// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12 // CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" "" struct [[deprecated]] Test8; Modified: cfe/trunk/test/Misc/ast-dump-color.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-color.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Misc/ast-dump-color.cpp (original) +++ cfe/trunk/test/Misc/ast-dump-color.cpp Thu Nov 8 16:41:36 2018 @@ -49,12 +49,14 @@ struct Invalid { //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} Modified: cfe/trunk/test/Misc/ast-dump-decl.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.c?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Misc/ast-dump-decl.c (original) +++ cfe/trunk/test/Misc/ast-dump-decl.c Thu Nov 8 16:41:36 2018 @@ -96,7 +96,8 @@ enum testEnumConstantDecl { }; // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int' // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int' -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral struct testIndirectFieldDecl { struct { @@ -140,7 +141,8 @@ struct testFieldDecl { }; // CHECK: FieldDecl{{.*}} TestFieldDecl 'int' // CHECK: FieldDecl{{.*}} TestFieldDeclWidth 'int' -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral // CHECK-MODULE: FieldDecl{{.*}} TestFieldDeclPrivate 'int' __module_private__ int TestVarDecl; Modified: cfe/trunk/test/Misc/ast-dump-decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Misc/ast-dump-decl.cpp (original) +++ cfe/trunk/test/Misc/ast-dump-decl.cpp Thu Nov 8 16:41:36 2018 @@ -381,7 +381,8 @@ namespace TestNonTypeTemplateParmDecl { // CHECK-NEXT: FunctionTemplateDecl // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I // CHECK-NEXT: TemplateArgument expr -// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr{{.*}} 'int' +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J namespace TestTemplateTemplateParmDecl { Modified: cfe/trunk/test/SemaCXX/compound-literal.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/compound-literal.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/compound-literal.cpp (original) +++ cfe/trunk/test/SemaCXX/compound-literal.cpp Thu Nov 8 16:41:36 2018 @@ -34,9 +34,18 @@ namespace brace_initializers { ~HasCtorDtor(); }; + POD p = (POD){1, 2}; + // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' + // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + void test() { (void)(POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' + // CHECK-NOT: ConstantExpr {{.*}} 'brace_initializers::POD' // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} @@ -52,6 +61,7 @@ namespace brace_initializers { #if __cplusplus >= 201103L (void)(HasCtor){1, 2}; // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor' + // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} @@ -59,7 +69,8 @@ namespace brace_initializers { (void)(HasCtorDtor){1, 2}; // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor' - // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor' + // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtorDtor' + // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} Modified: cfe/trunk/test/Tooling/clang-check-ast-dump.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-check-ast-dump.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-check-ast-dump.cpp (original) +++ cfe/trunk/test/Tooling/clang-check-ast-dump.cpp Thu Nov 8 16:41:36 2018 @@ -32,7 +32,8 @@ // CHECK-ATTR: test_namespace // CHECK-ATTR-NEXT: FieldDecl{{.*}}n // CHECK-ATTR-NEXT: AlignedAttr -// CHECK-ATTR-NEXT: BinaryOperator +// CHECK-ATTR-NEXT: ConstantExpr +// CHECK-ATTR-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s // CHECK-AFTER-NULL: class AfterNullNode Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Nov 8 16:41:36 2018 @@ -140,6 +140,7 @@ class TestImportBase : public Parameteri if (!Imported) return testing::AssertionFailure() << "Import failed, nullptr returned!"; + return Verifier.match(Imported, WrapperMatcher); } @@ -502,7 +503,6 @@ TEST_P(CanonicalRedeclChain, ShouldBeSam EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2)); } - TEST_P(ImportExpr, ImportStringLiteral) { MatchVerifier<Decl> Verifier; testImport( @@ -719,19 +719,18 @@ TEST_P(ImportExpr, ImportDesignatedInitE initListExpr( has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(1.0))), - has(integerLiteral(equals(2))))), + hasDescendant(floatLiteral(equals(1.0))), + hasDescendant(integerLiteral(equals(2))))), has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(2.0))), - has(integerLiteral(equals(2))))), + hasDescendant(floatLiteral(equals(2.0))), + hasDescendant(integerLiteral(equals(2))))), has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(1.0))), - has(integerLiteral(equals(0))))))))); + hasDescendant(floatLiteral(equals(1.0))), + hasDescendant(integerLiteral(equals(0))))))))); } - TEST_P(ImportExpr, ImportPredefinedExpr) { MatchVerifier<Decl> Verifier; // __func__ expands as StringLiteral("declToImport") Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Thu Nov 8 16:41:36 2018 @@ -760,23 +760,23 @@ TEST(Matcher, Initializers) { has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(1.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(2))))), has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(2.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(2))))), has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(1.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(0))))) ))))); } Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=346455&r1=346454&r2=346455&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Thu Nov 8 16:41:36 2018 @@ -1574,13 +1574,16 @@ TEST(SwitchCase, MatchesEachCase) { ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt())))))); EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(matchAndVerifyResultTrue( "void x() { switch (42) { case 1: case 2: case 3: default:; } }", switchStmt(forEachSwitchCase(caseStmt().bind("x"))), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits