Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -7203,7 +7203,7 @@ /// EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to /// GCC as we can manage. -static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) { +static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) { QualType ArgType = Arg->getType(); // __builtin_constant_p always has one operand. The rules which gcc follows @@ -7219,25 +7219,24 @@ // // FIXME: GCC also intends to return 1 for literals of aggregate types, but // its support for this does not currently work. - if (ArgType->isIntegralOrEnumerationType()) { - Expr::EvalResult Result; - if (!Arg->EvaluateAsRValue(Result, Ctx) || Result.HasSideEffects) + SpeculativeEvaluationRAII SpeculativeEval(Info); + FoldConstant Fold(Info, true); + if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() || + ArgType->isAnyComplexType()) { + APValue V; + if (!EvaluateAsRValue(Info, Arg, V) || Info.EvalStatus.HasSideEffects) return false; - - APValue &V = Result.Val; - if (V.getKind() == APValue::Int) + if (V.getKind() == APValue::Int || V.getKind() == APValue::Float || + V.getKind() == APValue::ComplexInt || + V.getKind() == APValue::ComplexFloat) return true; if (V.getKind() == APValue::LValue) return EvaluateBuiltinConstantPForLValue(V); - } else if (ArgType->isFloatingType() || ArgType->isAnyComplexType()) { - return Arg->isEvaluatable(Ctx); } else if (ArgType->isPointerType() || Arg->isGLValue()) { LValue LV; - Expr::EvalStatus Status; - EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold); if ((Arg->isGLValue() ? EvaluateLValue(Arg, LV, Info) : EvaluatePointer(Arg, LV, Info)) && - !Status.HasSideEffects) + !Info.EvalStatus.HasSideEffects) return EvaluateBuiltinConstantPForLValue(LV); } @@ -7628,7 +7627,7 @@ } case Builtin::BI__builtin_constant_p: - return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); + return Success(EvaluateBuiltinConstantP(Info, E->getArg(0)), E); case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: Index: test/SemaCXX/constant-expression-cxx11.cpp =================================================================== --- test/SemaCXX/constant-expression-cxx11.cpp +++ test/SemaCXX/constant-expression-cxx11.cpp @@ -2169,3 +2169,13 @@ constexpr int *q = (&n + 1) - (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element -3402}} constexpr int *r = &(&n + 1)[(unsigned __int128)-1]; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}} } + +namespace BuiltinConstantP { + int computeRuntime(int); + constexpr int compute(int x) { + return __builtin_constant_p(x) ? x + 2 : computeRuntime(x); + } + constexpr int x = compute(25); + int n; // expected-note{{declared here}} + constexpr int z = compute(n); // expected-error {{constant expression}} expected-note{{non-const variable}} +} Index: test/SemaCXX/constant-expression-cxx1y.cpp =================================================================== --- test/SemaCXX/constant-expression-cxx1y.cpp +++ test/SemaCXX/constant-expression-cxx1y.cpp @@ -982,3 +982,8 @@ int *p = &n; p += (__int128)(unsigned long)-1; // expected-note {{cannot refer to element 18446744073709551615 of non-array object in a constant expression}} } + +namespace BuiltinConstantP { + constexpr int f1(int i) { return __builtin_constant_p(i += 4) ? 0 : i += 3; } + static_assert(f1(10) == 13, ""); +}