Allow constant-folding of references which were formed in a manner not permitted
in a constant expression, for compatibility with g++. llvm-svn: 148020
This commit is contained in:
parent
4d4c988c6a
commit
02ab9c2940
|
@ -832,7 +832,8 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
|
||||||
|
|
||||||
/// Check that this reference or pointer core constant expression is a valid
|
/// Check that this reference or pointer core constant expression is a valid
|
||||||
/// value for an address or reference constant expression. Type T should be
|
/// value for an address or reference constant expression. Type T should be
|
||||||
/// either LValue or CCValue.
|
/// either LValue or CCValue. Return true if we can fold this expression,
|
||||||
|
/// whether or not it's a constant expression.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
|
static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
|
||||||
const T &LVal, APValue &Value,
|
const T &LVal, APValue &Value,
|
||||||
|
@ -854,19 +855,15 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
|
||||||
} else {
|
} else {
|
||||||
Info.Diag(E->getExprLoc());
|
Info.Diag(E->getExprLoc());
|
||||||
}
|
}
|
||||||
|
// Don't allow references to temporaries to escape.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsReferenceType = E->isGLValue();
|
bool IsReferenceType = E->isGLValue();
|
||||||
|
|
||||||
if (Designator.Invalid) {
|
if (Designator.Invalid) {
|
||||||
// This is not a core constant expression. A diagnostic will have already
|
// This is not a core constant expression. An appropriate diagnostic will
|
||||||
// been produced.
|
// have already been produced.
|
||||||
if (IsReferenceType)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Allow this for pointers, so we can fold things like integers cast to
|
|
||||||
// pointers.
|
|
||||||
Value = APValue(LVal.getLValueBase(), LVal.getLValueOffset(),
|
Value = APValue(LVal.getLValueBase(), LVal.getLValueOffset(),
|
||||||
APValue::NoLValuePath());
|
APValue::NoLValuePath());
|
||||||
return true;
|
return true;
|
||||||
|
@ -884,7 +881,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
|
||||||
if (!Base) {
|
if (!Base) {
|
||||||
// FIXME: diagnostic
|
// FIXME: diagnostic
|
||||||
Info.CCEDiag(E->getExprLoc());
|
Info.CCEDiag(E->getExprLoc());
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does this refer one past the end of some object?
|
// Does this refer one past the end of some object?
|
||||||
|
@ -897,7 +894,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
|
||||||
else
|
else
|
||||||
Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(),
|
Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(),
|
||||||
diag::note_constexpr_temporary_here);
|
diag::note_constexpr_temporary_here);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -134,8 +134,9 @@ namespace UndefinedBehavior {
|
||||||
constexpr const int &f(const int *q) {
|
constexpr const int &f(const int *q) {
|
||||||
return q[0]; // expected-note {{dereferenced pointer past the end of subobject of 's' is not a constant expression}}
|
return q[0]; // expected-note {{dereferenced pointer past the end of subobject of 's' is not a constant expression}}
|
||||||
}
|
}
|
||||||
|
constexpr int n = (f(p), 0); // expected-error {{constant expression}} expected-note {{in call to 'f(&s.m + 1)'}}
|
||||||
struct T {
|
struct T {
|
||||||
int n : f(p); // expected-error {{not an integer constant expression}} expected-note {{in call to 'f(&s.m + 1)'}}
|
int n : f(p); // expected-error {{not an integer constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ptr {
|
namespace Ptr {
|
||||||
|
|
|
@ -69,3 +69,10 @@ void UnfoldableAddrLabelDiff() { static __int128_t x = (long)&&a-(long)&&b; a:b:
|
||||||
// But make sure we do fold this.
|
// But make sure we do fold this.
|
||||||
// CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv
|
// CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv
|
||||||
void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;}
|
void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;}
|
||||||
|
|
||||||
|
// CHECK: @i = constant i32* bitcast (float* @PR9558 to i32*)
|
||||||
|
int &i = reinterpret_cast<int&>(PR9558);
|
||||||
|
|
||||||
|
int arr[2];
|
||||||
|
// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*)
|
||||||
|
int &pastEnd = arr[2];
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<link type="text/css" rel="stylesheet" href="content.css">
|
<link type="text/css" rel="stylesheet" href="content.css">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.none { background-color: #FFCCCC }
|
.none { background-color: #FFCCCC }
|
||||||
.partial { background-color: #FFFF99 }
|
.svn { background-color: #FFFF99 }
|
||||||
.full { background-color: #CCFF99 }
|
.full { background-color: #CCFF99 }
|
||||||
th { background-color: #FFDDAA }
|
th { background-color: #FFDDAA }
|
||||||
</style>
|
</style>
|
||||||
|
@ -156,7 +156,7 @@ with clang; other versions have not been tested.</p>
|
||||||
<td>
|
<td>
|
||||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf">N2764
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf">N2764
|
||||||
</a></td>
|
</a></td>
|
||||||
<td class="none" align="center">No</td>
|
<td class="svn" align="center">SVN</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Generalized attributes</td>
|
<td>Generalized attributes</td>
|
||||||
|
@ -238,7 +238,7 @@ with clang; other versions have not been tested.</p>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Extending <code>sizeof</code></td>
|
<td>Extending <code>sizeof</code></td>
|
||||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html">N2253</a></td>
|
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html">N2253</a></td>
|
||||||
<td class="none" align="center">No</td>
|
<td class="svn" align="center">SVN</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Inline namespaces</td>
|
<td>Inline namespaces</td>
|
||||||
|
|
Loading…
Reference in New Issue