r359361 - Revert Fix interactions between __builtin_constant_p and constexpr to match current trunk GCC.
Roman Lebedev via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 27 03:00:59 PDT 2019
On Sat, Apr 27, 2019 at 3:29 AM Jorge Gorbe Moya via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
>
> Author: jgorbe
> Date: Fri Apr 26 17:32:04 2019
> New Revision: 359361
>
> URL: http://llvm.org/viewvc/llvm-project?rev=359361&view=rev
> Log:
> Revert Fix interactions between __builtin_constant_p and constexpr to match current trunk GCC.
>
> This reverts r359059 (git commit 0b098754b73f3b96d00ecb1c7605760b11c90298)
It is common to specify the *reason* for the revert, so it is recorded
in change log.
> Removed:
> cfe/trunk/test/SemaCXX/builtin-constant-p.cpp
> Modified:
> cfe/trunk/lib/AST/ExprConstant.cpp
> cfe/trunk/lib/Sema/SemaChecking.cpp
> cfe/trunk/test/SemaCXX/enable_if.cpp
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=359361&r1=359360&r2=359361&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Apr 26 17:32:04 2019
> @@ -7801,33 +7801,19 @@ EvaluateBuiltinClassifyType(const CallEx
> }
>
> /// EvaluateBuiltinConstantPForLValue - Determine the result of
> -/// __builtin_constant_p when applied to the given pointer.
> +/// __builtin_constant_p when applied to the given lvalue.
> ///
> -/// A pointer is only "constant" if it is null (or a pointer cast to integer)
> -/// or it points to the first character of a string literal.
> -static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) {
> - APValue::LValueBase Base = LV.getLValueBase();
> - if (Base.isNull()) {
> - // A null base is acceptable.
> - return true;
> - } else if (const Expr *E = Base.dyn_cast<const Expr *>()) {
> - if (!isa<StringLiteral>(E))
> - return false;
> - return LV.getLValueOffset().isZero();
> - } else {
> - // Any other base is not constant enough for GCC.
> - return false;
> - }
> +/// An lvalue is only "constant" if it is a pointer or reference to the first
> +/// character of a string literal.
> +template<typename LValue>
> +static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
> + const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
> + return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
> }
>
> /// EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to
> /// GCC as we can manage.
> -static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
> - // Constant-folding is always enabled for the operand of __builtin_constant_p
> - // (even when the enclosing evaluation context otherwise requires a strict
> - // language-specific constant expression).
> - FoldConstant Fold(Info, true);
> -
> +static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) {
> QualType ArgType = Arg->getType();
>
> // __builtin_constant_p always has one operand. The rules which gcc follows
> @@ -7835,27 +7821,34 @@ static bool EvaluateBuiltinConstantP(Eva
> //
> // - If the operand is of integral, floating, complex or enumeration type,
> // and can be folded to a known value of that type, it returns 1.
> - // - If the operand can be folded to a pointer to the first character
> - // of a string literal (or such a pointer cast to an integral type)
> - // or to a null pointer or an integer cast to a pointer, it returns 1.
> + // - If the operand and can be folded to a pointer to the first character
> + // of a string literal (or such a pointer cast to an integral type), it
> + // returns 1.
> //
> // Otherwise, it returns 0.
> //
> // FIXME: GCC also intends to return 1 for literals of aggregate types, but
> // its support for this does not currently work.
> - if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
> - ArgType->isAnyComplexType() || ArgType->isPointerType() ||
> - ArgType->isNullPtrType()) {
> - APValue V;
> - if (!::EvaluateAsRValue(Info, Arg, V))
> + if (ArgType->isIntegralOrEnumerationType()) {
> + Expr::EvalResult Result;
> + if (!Arg->EvaluateAsRValue(Result, Ctx) || Result.HasSideEffects)
> return false;
>
> - // For a pointer (possibly cast to integer), there are special rules.
> + APValue &V = Result.Val;
> + if (V.getKind() == APValue::Int)
> + return true;
> if (V.getKind() == APValue::LValue)
> return EvaluateBuiltinConstantPForLValue(V);
> -
> - // Otherwise, any constant value is good enough.
> - return V.getKind() != APValue::Uninitialized;
> + } 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)
> + return EvaluateBuiltinConstantPForLValue(LV);
> }
>
> // Anything else isn't considered to be sufficiently constant.
> @@ -8266,7 +8259,7 @@ bool IntExprEvaluator::VisitBuiltinCallE
>
> case Builtin::BI__builtin_constant_p: {
> auto Arg = E->getArg(0);
> - if (EvaluateBuiltinConstantP(Info, Arg))
> + if (EvaluateBuiltinConstantP(Info.Ctx, Arg))
> return Success(true, E);
> auto ArgTy = Arg->IgnoreImplicit()->getType();
> if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) &&
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=359361&r1=359360&r2=359361&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Apr 26 17:32:04 2019
> @@ -1199,14 +1199,10 @@ Sema::CheckBuiltinFunctionCall(FunctionD
> if (checkArgCount(*this, TheCall, 1)) return true;
> TheCall->setType(Context.IntTy);
> break;
> - case Builtin::BI__builtin_constant_p: {
> + case Builtin::BI__builtin_constant_p:
> if (checkArgCount(*this, TheCall, 1)) return true;
> - ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
> - if (Arg.isInvalid()) return true;
> - TheCall->setArg(0, Arg.get());
> TheCall->setType(Context.IntTy);
> break;
> - }
> case Builtin::BI__builtin_launder:
> return SemaBuiltinLaunder(*this, TheCall);
> case Builtin::BI__sync_fetch_and_add:
>
> Removed: cfe/trunk/test/SemaCXX/builtin-constant-p.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-constant-p.cpp?rev=359360&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/builtin-constant-p.cpp (original)
> +++ cfe/trunk/test/SemaCXX/builtin-constant-p.cpp (removed)
> @@ -1,61 +0,0 @@
> -// RUN: %clang_cc1 -std=c++17 -verify %s
> -
> -using intptr_t = __INTPTR_TYPE__;
> -
> -// Test interaction of constexpr and __builtin_constant_p.
> -
> -template<typename T> constexpr bool bcp(T t) {
> - return __builtin_constant_p(t);
> -}
> -template<typename T> constexpr bool bcp_fold(T t) {
> - return __builtin_constant_p(((void)(intptr_t)&t, t));
> -}
> -
> -constexpr intptr_t ensure_fold_is_generally_not_enabled = // expected-error {{constant expression}}
> - (intptr_t)&ensure_fold_is_generally_not_enabled; // expected-note {{cast}}
> -
> -constexpr intptr_t ptr_to_int(const void *p) {
> - return __builtin_constant_p(1) ? (intptr_t)p : (intptr_t)p;
> -}
> -
> -constexpr int *int_to_ptr(intptr_t n) {
> - return __builtin_constant_p(1) ? (int*)n : (int*)n;
> -}
> -
> -int x;
> -
> -// Integer and floating point constants encountered during constant expression
> -// evaluation are considered constant. So is nullptr_t.
> -static_assert(bcp(1));
> -static_assert(bcp_fold(1));
> -static_assert(bcp(1.0));
> -static_assert(bcp_fold(1.0));
> -static_assert(bcp(nullptr));
> -static_assert(bcp_fold(nullptr));
> -
> -// Pointers to the start of strings are considered constant.
> -static_assert(bcp("foo"));
> -static_assert(bcp_fold("foo"));
> -
> -// Null pointers are considered constant.
> -static_assert(bcp<int*>(nullptr));
> -static_assert(bcp_fold<int*>(nullptr));
> -static_assert(bcp<const char*>(nullptr));
> -static_assert(bcp_fold<const char*>(nullptr));
> -
> -// Other pointers are not.
> -static_assert(!bcp(&x));
> -static_assert(!bcp_fold(&x));
> -
> -// Pointers cast to integers follow the rules for pointers.
> -static_assert(bcp(ptr_to_int("foo")));
> -static_assert(bcp_fold(ptr_to_int("foo")));
> -static_assert(!bcp(ptr_to_int(&x)));
> -static_assert(!bcp_fold(ptr_to_int(&x)));
> -
> -// Integers cast to pointers follow the integer rules.
> -static_assert(bcp(int_to_ptr(0)));
> -static_assert(bcp_fold(int_to_ptr(0)));
> -static_assert(bcp(int_to_ptr(123))); // GCC rejects these due to not recognizing
> -static_assert(bcp_fold(int_to_ptr(123))); // the bcp conditional in 'int_to_ptr' ...
> -static_assert(__builtin_constant_p((int*)123)); // ... but GCC accepts this
>
> Modified: cfe/trunk/test/SemaCXX/enable_if.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enable_if.cpp?rev=359361&r1=359360&r2=359361&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/enable_if.cpp (original)
> +++ cfe/trunk/test/SemaCXX/enable_if.cpp Fri Apr 26 17:32:04 2019
> @@ -522,14 +522,3 @@ void test() {
> InConstantContext::foo("abc");
> }
> } // namespace InConstantContext
> -
> -namespace StringLiteralDetector {
> - void need_string_literal(const char *p) __attribute__((enable_if(__builtin_constant_p(p), "argument is not a string literal"))); // expected-note 2{{not a string literal}}
> - void test(const char *unknown) {
> - need_string_literal("foo");
> - need_string_literal(unknown); // expected-error {{no matching function}}
> - constexpr char str[] = "bar";
> - need_string_literal(str); // expected-error {{no matching function}}
> - }
> -}
> -
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list