Author: void Date: Tue Nov 20 00:53:30 2018 New Revision: 347294 URL: http://llvm.org/viewvc/llvm-project?rev=347294&view=rev Log: Use is.constant intrinsic for __builtin_constant_p
Summary: A __builtin_constant_p may end up with a constant after inlining. Use the is.constant intrinsic if it's a variable that's in a context where it may resolve to a constant, e.g., an argument to a function after inlining. Reviewers: rsmith, shafik Subscribers: jfb, kristina, cfe-commits, nickdesaulniers, jyknight Differential Revision: https://reviews.llvm.org/D54355 Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/test/Analysis/builtin-functions.cpp cfe/trunk/test/Sema/builtins.c cfe/trunk/test/SemaCXX/compound-literal.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Tue Nov 20 00:53:30 2018 @@ -901,10 +901,15 @@ public: /// ConstantExpr - An expression that occurs in a constant context. class ConstantExpr : public FullExpr { -public: ConstantExpr(Expr *subexpr) : FullExpr(ConstantExprClass, subexpr) {} +public: + static ConstantExpr *Create(const ASTContext &Context, Expr *E) { + assert(!isa<ConstantExpr>(E)); + return new (Context) ConstantExpr(E); + } + /// Build an empty constant expression wrapper. explicit ConstantExpr(EmptyShell Empty) : FullExpr(ConstantExprClass, Empty) {} @@ -3091,8 +3096,8 @@ inline Expr *Expr::IgnoreImpCasts() { while (true) if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e)) e = ice->getSubExpr(); - else if (ConstantExpr *ce = dyn_cast<ConstantExpr>(e)) - e = ce->getSubExpr(); + else if (FullExpr *fe = dyn_cast<FullExpr>(e)) + e = fe->getSubExpr(); else break; return e; Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 20 00:53:30 2018 @@ -6375,7 +6375,7 @@ ExpectedStmt ASTNodeImporter::VisitConst Expr *ToSubExpr; std::tie(ToSubExpr) = *Imp; - return new (Importer.getToContext()) ConstantExpr(ToSubExpr); + return ConstantExpr::Create(Importer.getToContext(), ToSubExpr); } ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Tue Nov 20 00:53:30 2018 @@ -2594,8 +2594,8 @@ Expr *Expr::IgnoreParenCasts() { E = NTTP->getReplacement(); continue; } - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { - E = CE->getSubExpr(); + if (FullExpr *FE = dyn_cast<FullExpr>(E)) { + E = FE->getSubExpr(); continue; } return E; @@ -2619,8 +2619,8 @@ Expr *Expr::IgnoreCasts() { E = NTTP->getReplacement(); continue; } - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { - E = CE->getSubExpr(); + if (FullExpr *FE = dyn_cast<FullExpr>(E)) { + E = FE->getSubExpr(); continue; } return E; @@ -2648,8 +2648,8 @@ Expr *Expr::IgnoreParenLValueCasts() { = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) { E = NTTP->getReplacement(); continue; - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) { - E = CE->getSubExpr(); + } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) { + E = FE->getSubExpr(); continue; } break; @@ -2920,6 +2920,12 @@ bool Expr::isConstantInitializer(ASTCont break; } + case ConstantExprClass: { + // FIXME: We should be able to return "true" here, but it can lead to extra + // error messages. E.g. in Sema/array-init.c. + const Expr *Exp = cast<ConstantExpr>(this)->getSubExpr(); + return Exp->isConstantInitializer(Ctx, false, Culprit); + } case CompoundLiteralExprClass: { // This handles gcc's extension that allows global initializers like // "struct x {int x;} x = (struct x) {};". Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Nov 20 00:53:30 2018 @@ -45,6 +45,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include <cstring> #include <functional> @@ -721,6 +722,10 @@ namespace { /// Whether or not we're currently speculatively evaluating. bool IsSpeculativelyEvaluating; + /// Whether or not we're in a context where the front end requires a + /// constant value. + bool InConstantContext; + enum EvaluationMode { /// Evaluate as a constant expression. Stop if we find that the expression /// is not a constant expression. @@ -782,7 +787,7 @@ namespace { EvaluatingDecl((const ValueDecl *)nullptr), EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false), HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false), - EvalMode(Mode) {} + InConstantContext(false), EvalMode(Mode) {} void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { EvaluatingDecl = Base; @@ -7348,6 +7353,8 @@ public: // Visitor Methods //===--------------------------------------------------------------------===// + bool VisitConstantExpr(const ConstantExpr *E); + bool VisitIntegerLiteral(const IntegerLiteral *E) { return Success(E->getValue(), E); } @@ -8088,6 +8095,11 @@ static bool tryEvaluateBuiltinObjectSize return true; } +bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) { + llvm::SaveAndRestore<bool> InConstantContext(Info.InConstantContext, true); + return ExprEvaluatorBaseTy::VisitConstantExpr(E); +} + bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { if (unsigned BuiltinOp = E->getBuiltinCallee()) return VisitBuiltinCallExpr(E, BuiltinOp); @@ -8175,8 +8187,20 @@ bool IntExprEvaluator::VisitBuiltinCallE return Success(Val.countLeadingZeros(), E); } - case Builtin::BI__builtin_constant_p: - return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); + case Builtin::BI__builtin_constant_p: { + auto Arg = E->getArg(0); + if (EvaluateBuiltinConstantP(Info.Ctx, Arg)) + return Success(true, E); + auto ArgTy = Arg->IgnoreImplicit()->getType(); + if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) && + !ArgTy->isAggregateType() && !ArgTy->isPointerType()) { + // We can delay calculation of __builtin_constant_p until after + // inlining. Note: This diagnostic won't be shown to the user. + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); + return false; + } + return Success(false, E); + } case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: @@ -10746,6 +10770,14 @@ static bool FastEvaluateAsRValue(const E return false; } +static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result, + const ASTContext &Ctx, EvalInfo &Info) { + bool IsConst; + if (FastEvaluateAsRValue(E, Result, Ctx, IsConst)) + return IsConst; + + return EvaluateAsRValue(Info, E, Result.Val); +} /// EvaluateAsRValue - Return true if this is a constant which we can fold using /// any crazy technique (that has nothing to do with language standards) that @@ -10753,12 +10785,8 @@ static bool FastEvaluateAsRValue(const E /// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion /// will be applied to the result. bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const { - bool IsConst; - if (FastEvaluateAsRValue(this, Result, Ctx, IsConst)) - return IsConst; - EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); - return ::EvaluateAsRValue(Info, this, Result.Val); + return ::EvaluateAsRValue(this, Result, Ctx, Info); } bool Expr::EvaluateAsBooleanCondition(bool &Result, @@ -10878,35 +10906,40 @@ bool Expr::isEvaluatable(const ASTContex APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const { - EvalResult EvalResult; - EvalResult.Diag = Diag; - bool Result = EvaluateAsRValue(EvalResult, Ctx); + EvalResult EVResult; + EVResult.Diag = Diag; + EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects); + Info.InConstantContext = true; + + bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info); (void)Result; assert(Result && "Could not evaluate expression"); - assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); + assert(EVResult.Val.isInt() && "Expression did not evaluate to integer"); - return EvalResult.Val.getInt(); + return EVResult.Val.getInt(); } APSInt Expr::EvaluateKnownConstIntCheckOverflow( const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const { - EvalResult EvalResult; - EvalResult.Diag = Diag; - EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); - bool Result = ::EvaluateAsRValue(Info, this, EvalResult.Val); + EvalResult EVResult; + EVResult.Diag = Diag; + EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow); + Info.InConstantContext = true; + + bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val); (void)Result; assert(Result && "Could not evaluate expression"); - assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); + assert(EVResult.Val.isInt() && "Expression did not evaluate to integer"); - return EvalResult.Val.getInt(); + return EVResult.Val.getInt(); } void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { bool IsConst; - EvalResult EvalResult; - if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) { - EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); - (void)::EvaluateAsRValue(Info, this, EvalResult.Val); + EvalResult EVResult; + if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) { + EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow); + (void)::EvaluateAsRValue(Info, this, EVResult.Val); } } @@ -10959,7 +10992,11 @@ static ICEDiag Worst(ICEDiag A, ICEDiag static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) { Expr::EvalResult EVResult; - if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects || + Expr::EvalStatus Status; + EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression); + + Info.InConstantContext = true; + if (!::EvaluateAsRValue(E, EVResult, Ctx, Info) || EVResult.HasSideEffects || !EVResult.Val.isInt()) return ICEDiag(IK_NotICE, E->getBeginLoc()); Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Nov 20 00:53:30 2018 @@ -1926,6 +1926,26 @@ RValue CodeGenFunction::EmitBuiltinExpr( case Builtin::BI__builtin_rotateright64: return emitRotate(E, true); + case Builtin::BI__builtin_constant_p: { + llvm::Type *ResultType = ConvertType(E->getType()); + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + // At -O0, we don't perform inlining, so we don't need to delay the + // processing. + return RValue::get(ConstantInt::get(ResultType, 0)); + if (auto *DRE = dyn_cast<DeclRefExpr>(E->getArg(0)->IgnoreImplicit())) { + auto DREType = DRE->getType(); + if (DREType->isAggregateType() || DREType->isFunctionType()) + return RValue::get(ConstantInt::get(ResultType, 0)); + } + Value *ArgValue = EmitScalarExpr(E->getArg(0)); + llvm::Type *ArgType = ArgValue->getType(); + + Value *F = CGM.getIntrinsic(Intrinsic::is_constant, ArgType); + Value *Result = Builder.CreateCall(F, ArgValue); + if (Result->getType() != ResultType) + Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true); + return RValue::get(Result); + } case Builtin::BI__builtin_object_size: { unsigned Type = E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Nov 20 00:53:30 2018 @@ -13861,6 +13861,8 @@ Decl *Sema::BuildStaticAssertDeclaration ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr); if (Converted.isInvalid()) Failed = true; + else + Converted = ConstantExpr::Create(Context, Converted.get()); llvm::APSInt Cond; if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 20 00:53:30 2018 @@ -5795,6 +5795,8 @@ Sema::BuildCompoundLiteralExpr(SourceLoc ? VK_RValue : VK_LValue; + if (isFileScope) + LiteralExpr = ConstantExpr::Create(Context, LiteralExpr); Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr, isFileScope); if (isFileScope) { @@ -5803,7 +5805,6 @@ Sema::BuildCompoundLiteralExpr(SourceLoc !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: @@ -14167,12 +14168,15 @@ Sema::VerifyIntegerConstantExpression(Ex return ExprError(); } + if (!isa<ConstantExpr>(E)) + E = ConstantExpr::Create(Context, E); + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstIntCheckOverflow(Context); - return new (Context) ConstantExpr(E); + return E; } Expr::EvalResult EvalResult; @@ -14190,7 +14194,7 @@ Sema::VerifyIntegerConstantExpression(Ex if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); - return new (Context) ConstantExpr(E); + return E; } // If our only note is the usual "invalid subexpression" note, just point @@ -14218,7 +14222,7 @@ Sema::VerifyIntegerConstantExpression(Ex if (Result) *Result = EvalResult.Val.getInt(); - return new (Context) ConstantExpr(E); + return E; } namespace { Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Nov 20 00:53:30 2018 @@ -5469,7 +5469,7 @@ static ExprResult CheckConvertedConstant if (Notes.empty()) { // It's a constant expression. - return new (S.Context) ConstantExpr(Result.get()); + return ConstantExpr::Create(S.Context, Result.get()); } } Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Nov 20 00:53:30 2018 @@ -178,6 +178,8 @@ getDeducedParameterFromExpr(TemplateDedu while (true) { if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E)) E = IC->getSubExpr(); + else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) + E = CE->getSubExpr(); else if (SubstNonTypeTemplateParmExpr *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) E = Subst->getReplacement(); @@ -5225,6 +5227,8 @@ MarkUsedTemplateParameters(ASTContext &C while (true) { if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) E = ICE->getSubExpr(); + else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) + E = CE->getSubExpr(); else if (const SubstNonTypeTemplateParmExpr *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) E = Subst->getReplacement(); Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Tue Nov 20 00:53:30 2018 @@ -2233,10 +2233,6 @@ 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/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Nov 20 00:53:30 2018 @@ -1283,9 +1283,6 @@ void ExprEngine::Visit(const Stmt *S, Ex 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/Analysis/builtin-functions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/builtin-functions.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/test/Analysis/builtin-functions.cpp (original) +++ cfe/trunk/test/Analysis/builtin-functions.cpp Tue Nov 20 00:53:30 2018 @@ -70,14 +70,14 @@ void test_constant_p() { const int j = 2; constexpr int k = 3; clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} } Modified: cfe/trunk/test/Sema/builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtins.c?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/test/Sema/builtins.c (original) +++ cfe/trunk/test/Sema/builtins.c Tue Nov 20 00:53:30 2018 @@ -122,6 +122,14 @@ int test16() { __builtin_constant_p(1, 2); // expected-error {{too many arguments}} } +// __builtin_constant_p cannot resolve non-constants as a file scoped array. +int expr; +char y[__builtin_constant_p(expr) ? -1 : 1]; // no warning, the builtin is false. + +// no warning, the builtin is false. +struct foo { int a; }; +struct foo x = (struct foo) { __builtin_constant_p(42) ? 37 : 927 }; + const int test17_n = 0; const char test17_c[] = {1, 2, 3, 0}; const char test17_d[] = {1, 2, 3, 4}; @@ -161,6 +169,7 @@ void test17() { F(&test17_d); F((struct Aggregate){0, 1}); F((IntVector){0, 1, 2, 3}); + F(test17); // Ensure that a technique used in glibc is handled correctly. #define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4) Modified: cfe/trunk/test/SemaCXX/compound-literal.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/compound-literal.cpp?rev=347294&r1=347293&r2=347294&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/compound-literal.cpp (original) +++ cfe/trunk/test/SemaCXX/compound-literal.cpp Tue Nov 20 00:53:30 2018 @@ -36,8 +36,8 @@ namespace brace_initializers { POD p = (POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' - // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' - // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: ConstantExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits