forked from OSchip/llvm-project
[Parse] Allow 'constexpr' in condition declarations
This patch implements the functionality specified by DR948. The changes are two fold. First, the parser was modified to allow 'constexpr's to appear in condition declarations (which was a hard error before). Second, Sema was modified to cleanup maybe odr-used declarations by way of a call to 'ActOnFinishFullExpr'. As 'constexpr's were not allowed in condition declarations before the cleanup wasn't necessary (such declarations were always odr-used). This fixes PR22491. Differential Revision: http://reviews.llvm.org/D8978 llvm-svn: 240707
This commit is contained in:
parent
9b921e5dc9
commit
f0af05c4a5
|
@ -1705,6 +1705,7 @@ private:
|
|||
DSC_top_level, // top-level/namespace declaration context
|
||||
DSC_template_type_arg, // template type argument context
|
||||
DSC_objc_method_result, // ObjC method result context, enables 'instancetype'
|
||||
DSC_condition // condition declaration context
|
||||
};
|
||||
|
||||
/// Is this a context in which we are parsing just a type-specifier (or
|
||||
|
@ -1715,6 +1716,7 @@ private:
|
|||
case DSC_class:
|
||||
case DSC_top_level:
|
||||
case DSC_objc_method_result:
|
||||
case DSC_condition:
|
||||
return false;
|
||||
|
||||
case DSC_template_type_arg:
|
||||
|
|
|
@ -2173,7 +2173,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
|
|||
}
|
||||
|
||||
// Issue diagnostic and remove constexpr specfier if present.
|
||||
if (DS.isConstexprSpecified()) {
|
||||
if (DS.isConstexprSpecified() && DSC != DSC_condition) {
|
||||
Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
|
||||
DS.ClearConstexprSpec();
|
||||
}
|
||||
|
|
|
@ -1686,7 +1686,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
|
|||
// type-specifier-seq
|
||||
DeclSpec DS(AttrFactory);
|
||||
DS.takeAttributesFrom(attrs);
|
||||
ParseSpecifierQualifierList(DS);
|
||||
ParseSpecifierQualifierList(DS, AS_none, DSC_condition);
|
||||
|
||||
// declarator
|
||||
Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
|
||||
|
|
|
@ -495,6 +495,7 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
|
|||
if (CondVar) {
|
||||
ConditionVar = cast<VarDecl>(CondVar);
|
||||
CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
|
||||
CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);
|
||||
if (CondResult.isInvalid())
|
||||
return StmtError();
|
||||
}
|
||||
|
@ -649,12 +650,10 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
|
|||
if (CondResult.isInvalid()) return StmtError();
|
||||
Cond = CondResult.get();
|
||||
|
||||
if (!CondVar) {
|
||||
CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
|
||||
if (CondResult.isInvalid())
|
||||
return StmtError();
|
||||
Cond = CondResult.get();
|
||||
}
|
||||
CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
|
||||
if (CondResult.isInvalid())
|
||||
return StmtError();
|
||||
Cond = CondResult.get();
|
||||
|
||||
getCurFunction()->setHasBranchIntoScope();
|
||||
|
||||
|
@ -1229,6 +1228,7 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
|
|||
if (CondVar) {
|
||||
ConditionVar = cast<VarDecl>(CondVar);
|
||||
CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
|
||||
CondResult = ActOnFinishFullExpr(CondResult.get(), WhileLoc);
|
||||
if (CondResult.isInvalid())
|
||||
return StmtError();
|
||||
}
|
||||
|
@ -1634,6 +1634,7 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
|
|||
if (secondVar) {
|
||||
ConditionVar = cast<VarDecl>(secondVar);
|
||||
SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
|
||||
SecondResult = ActOnFinishFullExpr(SecondResult.get(), ForLoc);
|
||||
if (SecondResult.isInvalid())
|
||||
return StmtError();
|
||||
}
|
||||
|
|
|
@ -44,3 +44,32 @@ namespace dr990 { // dr990: 3.5
|
|||
D d{};
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace dr948 { // dr948: 3.7
|
||||
#if __cplusplus >= 201103L
|
||||
class A {
|
||||
public:
|
||||
constexpr A(int v) : v(v) { }
|
||||
constexpr operator int() const { return v; }
|
||||
private:
|
||||
int v;
|
||||
};
|
||||
|
||||
constexpr int id(int x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
void f() {
|
||||
if (constexpr int i = id(101)) { }
|
||||
switch (constexpr int i = id(2)) { default: break; case 2: break; }
|
||||
for (; constexpr int i = id(0); ) { }
|
||||
while (constexpr int i = id(0)) { }
|
||||
|
||||
if (constexpr A i = 101) { }
|
||||
switch (constexpr A i = 2) { default: break; case 2: break; }
|
||||
for (; constexpr A i = 0; ) { }
|
||||
while (constexpr A i = 0) { }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue