forked from OSchip/llvm-project
Make the odr-use logic work correctly for constant-expressions. PR12006.
llvm-svn: 151699
This commit is contained in:
parent
d6d74c37ec
commit
c6237c6e05
|
@ -2341,6 +2341,8 @@ public:
|
|||
ExprResult TranformToPotentiallyEvaluated(Expr *E);
|
||||
ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
|
||||
|
||||
ExprResult ActOnConstantExpression(ExprResult Res);
|
||||
|
||||
// Functions for marking a declaration referenced. These functions also
|
||||
// contain the relevant logic for marking if a reference to a function or
|
||||
// variable is an odr-use (in the C++11 sense). There are separate variants
|
||||
|
|
|
@ -258,7 +258,8 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
|
|||
Sema::ConstantEvaluated);
|
||||
|
||||
ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
|
||||
return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
|
||||
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
|
||||
return Actions.ActOnConstantExpression(Res);
|
||||
}
|
||||
|
||||
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
|
||||
|
|
|
@ -10023,6 +10023,18 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) {
|
|||
MaybeODRUseExprs.erase(E->IgnoreParens());
|
||||
}
|
||||
|
||||
ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
|
||||
if (!Res.isUsable())
|
||||
return Res;
|
||||
|
||||
// If a constant-expression is a reference to a variable where we delay
|
||||
// deciding whether it is an odr-use, just assume we will apply the
|
||||
// lvalue-to-rvalue conversion. In the one case where this doesn't happen
|
||||
// (a non-type template argument), we have special handling anyway.
|
||||
UpdateMarkingForLValueToRValue(Res.get());
|
||||
return Res;
|
||||
}
|
||||
|
||||
void Sema::CleanupVarDeclMarking() {
|
||||
for (llvm::SmallPtrSetIterator<Expr*> i = MaybeODRUseExprs.begin(),
|
||||
e = MaybeODRUseExprs.end();
|
||||
|
|
|
@ -2950,6 +2950,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
|
|||
EnterExpressionEvaluationContext Unevaluated(getSema(),
|
||||
Sema::ConstantEvaluated);
|
||||
ExprResult E = getDerived().TransformExpr(SourceExpr);
|
||||
E = SemaRef.ActOnConstantExpression(E);
|
||||
SourceExpr = (E.isInvalid() ? 0 : E.take());
|
||||
}
|
||||
|
||||
|
@ -2990,6 +2991,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
|
|||
if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
|
||||
|
||||
ExprResult E = getDerived().TransformExpr(InputExpr);
|
||||
E = SemaRef.ActOnConstantExpression(E);
|
||||
if (E.isInvalid()) return true;
|
||||
Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
|
||||
return false;
|
||||
|
@ -3654,6 +3656,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
|
|||
EnterExpressionEvaluationContext Unevaluated(SemaRef,
|
||||
Sema::ConstantEvaluated);
|
||||
Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
|
||||
Size = SemaRef.ActOnConstantExpression(Size).take();
|
||||
}
|
||||
NewTL.setSizeExpr(Size);
|
||||
|
||||
|
@ -3744,6 +3747,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
|
|||
|
||||
ExprResult sizeResult
|
||||
= getDerived().TransformExpr(origSize);
|
||||
sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
|
||||
if (sizeResult.isInvalid())
|
||||
return QualType();
|
||||
|
||||
|
@ -3788,6 +3792,7 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
|
|||
Sema::ConstantEvaluated);
|
||||
|
||||
ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
||||
Size = SemaRef.ActOnConstantExpression(Size);
|
||||
if (Size.isInvalid())
|
||||
return QualType();
|
||||
|
||||
|
@ -5061,11 +5066,13 @@ TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
|
|||
|
||||
// Transform the left-hand case value.
|
||||
LHS = getDerived().TransformExpr(S->getLHS());
|
||||
LHS = SemaRef.ActOnConstantExpression(LHS);
|
||||
if (LHS.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
// Transform the right-hand case value (for the GNU case-range extension).
|
||||
RHS = getDerived().TransformExpr(S->getRHS());
|
||||
RHS = SemaRef.ActOnConstantExpression(RHS);
|
||||
if (RHS.isInvalid())
|
||||
return StmtError();
|
||||
}
|
||||
|
|
|
@ -52,9 +52,8 @@ void f1(int i) { // expected-note{{declared here}}
|
|||
auto m1 = [=]{
|
||||
int const M = 30;
|
||||
auto m2 = [i]{
|
||||
// FIXME: We odr-use here, but we shouldn't.
|
||||
// int x[N][M];
|
||||
// x[0][0] = i;
|
||||
int x[N][M];
|
||||
x[0][0] = i;
|
||||
};
|
||||
(void)N;
|
||||
(void)M;
|
||||
|
|
Loading…
Reference in New Issue