[Sema] Diagnose annotating `if constexpr` with a likelihood attribute
Adds a diagnostic when the user annotates an `if constexpr` with a likelihood attribute. The `if constexpr` statement is evaluated at compile time so the attribute has no effect. Annotating the accompanied `else` with a likelihood attribute has the same effect as annotating a generic statement. Since the attribute there is most likely not intended, a diagnostic will be issued. Since the attributes can't conflict, the "conflict" won't be diagnosed for an `if constexpr`. Differential Revision: https://reviews.llvm.org/D90336
This commit is contained in:
parent
b46fddf75f
commit
b231396122
|
@ -3162,6 +3162,11 @@ def warn_attribute_has_no_effect_on_infinite_loop : Warning<
|
|||
InGroup<IgnoredAttributes>;
|
||||
def note_attribute_has_no_effect_on_infinite_loop_here : Note<
|
||||
"annotating the infinite loop here">;
|
||||
def warn_attribute_has_no_effect_on_if_constexpr : Warning<
|
||||
"attribute %0 has no effect when annotating an 'if constexpr' statement">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def note_attribute_has_no_effect_on_if_constexpr_here : Note<
|
||||
"annotating the 'if constexpr' statement here">;
|
||||
def err_decl_attribute_invalid_on_stmt : Error<
|
||||
"%0 attribute cannot be applied to a statement">;
|
||||
def err_stmt_attribute_invalid_on_decl : Error<
|
||||
|
|
|
@ -600,6 +600,20 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr,
|
|||
DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), thenStmt,
|
||||
diag::warn_empty_if_body);
|
||||
|
||||
if (IsConstexpr) {
|
||||
auto DiagnoseLikelihood = [&](const Stmt *S) {
|
||||
if (const Attr *A = Stmt::getLikelihoodAttr(S)) {
|
||||
Diags.Report(A->getLocation(),
|
||||
diag::warn_attribute_has_no_effect_on_if_constexpr)
|
||||
<< A << A->getRange();
|
||||
Diags.Report(IfLoc,
|
||||
diag::note_attribute_has_no_effect_on_if_constexpr_here)
|
||||
<< SourceRange(IfLoc, LParenLoc.getLocWithOffset(-1));
|
||||
}
|
||||
};
|
||||
DiagnoseLikelihood(thenStmt);
|
||||
DiagnoseLikelihood(elseStmt);
|
||||
} else {
|
||||
std::tuple<bool, const Attr *, const Attr *> LHC =
|
||||
Stmt::determineLikelihoodConflict(thenStmt, elseStmt);
|
||||
if (std::get<0>(LHC)) {
|
||||
|
@ -611,6 +625,7 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr,
|
|||
Diags.Report(ElseAttr->getLocation(), diag::note_conflicting_attribute)
|
||||
<< ElseAttr << ElseAttr->getRange();
|
||||
}
|
||||
}
|
||||
|
||||
return BuildIfStmt(IfLoc, IsConstexpr, LParenLoc, InitStmt, Cond, RParenLoc,
|
||||
thenStmt, ElseLoc, elseStmt);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 %s -fsyntax-only -verify
|
||||
// RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify
|
||||
// RUN: %clang_cc1 %s -DPEDANTIC -pedantic -fsyntax-only -verify
|
||||
|
||||
#if PEDANTIC
|
||||
|
@ -129,4 +129,23 @@ void n() [[likely]] // expected-error {{'likely' attribute cannot be applied to
|
|||
catch (...) [[likely]] { // expected-error {{expected expression}}
|
||||
}
|
||||
}
|
||||
|
||||
void o()
|
||||
{
|
||||
// expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
|
||||
// expected-note@+1 {{annotating the 'if constexpr' statement here}}
|
||||
if constexpr (true) [[likely]];
|
||||
|
||||
// expected-note@+1 {{annotating the 'if constexpr' statement here}}
|
||||
if constexpr (true) {
|
||||
// expected-warning@+1 {{attribute 'unlikely' has no effect when annotating an 'if constexpr' statement}}
|
||||
} else [[unlikely]];
|
||||
|
||||
// Annotating both branches with conflicting likelihoods generates no diagnostic regarding the conflict.
|
||||
// expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
|
||||
// expected-note@+1 2 {{annotating the 'if constexpr' statement here}}
|
||||
if constexpr (true) [[likely]] {
|
||||
// expected-warning@+1 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
|
||||
} else [[likely]];
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue