зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
5d1f496f86
Коммит
5930a4c522
|
@ -3453,7 +3453,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Success(const CCValue &V, const Expr *E) {
|
bool Success(const CCValue &V, const Expr *E) {
|
||||||
if (V.isLValue()) {
|
if (V.isLValue() || V.isAddrLabelDiff()) {
|
||||||
Result = V;
|
Result = V;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4002,8 +4002,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
if (!HasSameBase(LHSValue, RHSValue)) {
|
if (!HasSameBase(LHSValue, RHSValue)) {
|
||||||
if (E->getOpcode() == BO_Sub) {
|
if (E->getOpcode() == BO_Sub) {
|
||||||
// Handle &&A - &&B.
|
// 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())
|
if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
|
||||||
return false;
|
return false;
|
||||||
const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr*>();
|
const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr*>();
|
||||||
|
@ -4014,6 +4012,10 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
|
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
|
||||||
if (!LHSAddrExpr || !RHSAddrExpr)
|
if (!LHSAddrExpr || !RHSAddrExpr)
|
||||||
return false;
|
return false;
|
||||||
|
// Make sure both labels come from the same function.
|
||||||
|
if (LHSAddrExpr->getLabel()->getDeclContext() !=
|
||||||
|
RHSAddrExpr->getLabel()->getDeclContext())
|
||||||
|
return false;
|
||||||
Result = CCValue(LHSAddrExpr, RHSAddrExpr);
|
Result = CCValue(LHSAddrExpr, RHSAddrExpr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4113,8 +4115,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
|
|
||||||
if (E->getOpcode() == BO_Sub && LHSVal.isLValue() && RHSVal.isLValue()) {
|
if (E->getOpcode() == BO_Sub && LHSVal.isLValue() && RHSVal.isLValue()) {
|
||||||
// Handle (intptr_t)&&A - (intptr_t)&&B.
|
// 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() ||
|
if (!LHSVal.getLValueOffset().isZero() ||
|
||||||
!RHSVal.getLValueOffset().isZero())
|
!RHSVal.getLValueOffset().isZero())
|
||||||
return false;
|
return false;
|
||||||
|
@ -4126,6 +4126,10 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
|
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
|
||||||
if (!LHSAddrExpr || !RHSAddrExpr)
|
if (!LHSAddrExpr || !RHSAddrExpr)
|
||||||
return false;
|
return false;
|
||||||
|
// Make sure both labels come from the same function.
|
||||||
|
if (LHSAddrExpr->getLabel()->getDeclContext() !=
|
||||||
|
RHSAddrExpr->getLabel()->getDeclContext())
|
||||||
|
return false;
|
||||||
Result = CCValue(LHSAddrExpr, RHSAddrExpr);
|
Result = CCValue(LHSAddrExpr, RHSAddrExpr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1034,7 +1034,7 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
|
||||||
RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy);
|
RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy);
|
||||||
llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
|
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
|
// address-of-label difference; make sure to truncate after
|
||||||
// the subtraction.
|
// the subtraction.
|
||||||
return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
|
return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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"}}
|
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}}
|
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;
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче