[clang] b231396 - [Sema] Diagnose annotating `if constexpr` with a likelihood attribute
Mark de Wever via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 31 09:52:01 PDT 2020
Author: Mark de Wever
Date: 2020-10-31T17:51:36+01:00
New Revision: b231396122f131ffaff5fc4ba36685a7df554aaa
URL: https://github.com/llvm/llvm-project/commit/b231396122f131ffaff5fc4ba36685a7df554aaa
DIFF: https://github.com/llvm/llvm-project/commit/b231396122f131ffaff5fc4ba36685a7df554aaa.diff
LOG: [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
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaStmt.cpp
clang/test/SemaCXX/attr-likelihood.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2b19eac7e0c8..7555a5ebbd34 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e6314fd65f8c..2672cadfa421 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -600,16 +600,31 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr,
DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), thenStmt,
diag::warn_empty_if_body);
- std::tuple<bool, const Attr *, const Attr *> LHC =
- Stmt::determineLikelihoodConflict(thenStmt, elseStmt);
- if (std::get<0>(LHC)) {
- const Attr *ThenAttr = std::get<1>(LHC);
- const Attr *ElseAttr = std::get<2>(LHC);
- Diags.Report(ThenAttr->getLocation(),
- diag::warn_attributes_likelihood_ifstmt_conflict)
- << ThenAttr << ThenAttr->getRange();
- Diags.Report(ElseAttr->getLocation(), diag::note_conflicting_attribute)
- << ElseAttr << ElseAttr->getRange();
+ 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)) {
+ const Attr *ThenAttr = std::get<1>(LHC);
+ const Attr *ElseAttr = std::get<2>(LHC);
+ Diags.Report(ThenAttr->getLocation(),
+ diag::warn_attributes_likelihood_ifstmt_conflict)
+ << ThenAttr << ThenAttr->getRange();
+ Diags.Report(ElseAttr->getLocation(), diag::note_conflicting_attribute)
+ << ElseAttr << ElseAttr->getRange();
+ }
}
return BuildIfStmt(IfLoc, IsConstexpr, LParenLoc, InitStmt, Cond, RParenLoc,
diff --git a/clang/test/SemaCXX/attr-likelihood.cpp b/clang/test/SemaCXX/attr-likelihood.cpp
index c8be00bfcc32..d2f95d17069c 100644
--- a/clang/test/SemaCXX/attr-likelihood.cpp
+++ b/clang/test/SemaCXX/attr-likelihood.cpp
@@ -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 at +2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
+ // expected-note at +1 {{annotating the 'if constexpr' statement here}}
+ if constexpr (true) [[likely]];
+
+ // expected-note at +1 {{annotating the 'if constexpr' statement here}}
+ if constexpr (true) {
+ // expected-warning at +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 at +2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
+ // expected-note at +1 2 {{annotating the 'if constexpr' statement here}}
+ if constexpr (true) [[likely]] {
+ // expected-warning at +1 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
+ } else [[likely]];
+}
#endif
More information about the cfe-commits
mailing list