From: Eli Friedman Date: Thu, 5 Jan 2012 23:59:40 +0000 (+0000) Subject: Address Richard's review comments on r147561 (Evaluate support for address-of-label... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5930a4c5224eea3b0558655f7f8c9ea027ef573e;p=clang Address Richard's review comments on r147561 (Evaluate support for address-of-label differences). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147631 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index fc214bfa80..949988db1a 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -3453,7 +3453,7 @@ public: } bool Success(const CCValue &V, const Expr *E) { - if (V.isLValue()) { + if (V.isLValue() || V.isAddrLabelDiff()) { Result = V; return true; } @@ -4002,8 +4002,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (!HasSameBase(LHSValue, RHSValue)) { if (E->getOpcode() == BO_Sub) { // Handle &&A - &&B. - // FIXME: We're missing a check that both labels have the same - // associated function; I'm not sure how to write this check. if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero()) return false; const Expr *LHSExpr = LHSValue.Base.dyn_cast(); @@ -4014,6 +4012,10 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { const AddrLabelExpr *RHSAddrExpr = dyn_cast(RHSExpr); if (!LHSAddrExpr || !RHSAddrExpr) return false; + // Make sure both labels come from the same function. + if (LHSAddrExpr->getLabel()->getDeclContext() != + RHSAddrExpr->getLabel()->getDeclContext()) + return false; Result = CCValue(LHSAddrExpr, RHSAddrExpr); return true; } @@ -4113,8 +4115,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (E->getOpcode() == BO_Sub && LHSVal.isLValue() && RHSVal.isLValue()) { // Handle (intptr_t)&&A - (intptr_t)&&B. - // FIXME: We're missing a check that both labels have the same - // associated function; I'm not sure how to write this check. if (!LHSVal.getLValueOffset().isZero() || !RHSVal.getLValueOffset().isZero()) return false; @@ -4126,6 +4126,10 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { const AddrLabelExpr *RHSAddrExpr = dyn_cast(RHSExpr); if (!LHSAddrExpr || !RHSAddrExpr) return false; + // Make sure both labels come from the same function. + if (LHSAddrExpr->getLabel()->getDeclContext() != + RHSAddrExpr->getLabel()->getDeclContext()) + return false; Result = CCValue(LHSAddrExpr, RHSAddrExpr); return true; } diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 2c151328c7..826a950148 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -1034,7 +1034,7 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy); llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS); - // LLVM os a bit sensitive about the exact format of the + // LLVM is a bit sensitive about the exact format of the // address-of-label difference; make sure to truncate after // the subtraction. return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType); diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp new file mode 100644 index 0000000000..5ec9a690f9 --- /dev/null +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++11 | FileCheck %s + +namespace CrossFuncLabelDiff { + // Make sure we refuse to constant-fold the variable b. + constexpr long a() { return (long)&&lbl + (0 && ({lbl: 0;})); } + void test() { static long b = (long)&&lbl - a(); lbl: return; } + // CHECK: sub nsw i64 ptrtoint (i8* blockaddress(@_ZN18CrossFuncLabelDiff4testEv, {{.*}}) to i64), + // CHECK: store i64 {{.*}}, i64* @_ZZN18CrossFuncLabelDiff4testEvE1b, align 8 +} diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index 03768c09fb..2e0eb9c23d 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -89,3 +89,10 @@ constexpr wchar_t wc = get(L"test\0\\\"\t\a\b\234\u1234"); // \ expected-error {{}} expected-note {{L"test\000\\\"\t\a\b\234\u1234"}} constexpr char32_t c32_err = get(U"\U00110000"); // expected-error {{invalid universal character}} + +typedef decltype(sizeof(int)) LabelDiffTy; +constexpr LabelDiffTy mulBy3(LabelDiffTy x) { return x * 3; } // expected-note {{subexpression}} +void LabelDiffTest() { + static_assert(mulBy3((LabelDiffTy)&&a-(LabelDiffTy)&&b) == 3, ""); // expected-error {{constant expression}} expected-note {{call to 'mulBy3(&&a - &&b)'}} + a:b:return; +}