[llvm-branch-commits] [clang] 318677e - [Sema] Avoid Wrange-loop-analysis false positives

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 23 11:05:51 PST 2020


Author: Mark de Wever
Date: 2020-01-23T20:04:04+01:00
New Revision: 318677e78def0023d210a29f4b3cf648e02f9fdc

URL: https://github.com/llvm/llvm-project/commit/318677e78def0023d210a29f4b3cf648e02f9fdc
DIFF: https://github.com/llvm/llvm-project/commit/318677e78def0023d210a29f4b3cf648e02f9fdc.diff

LOG: [Sema] Avoid Wrange-loop-analysis false positives

When Wrange-loop-analysis issues a diagnostic on a dependent type in a
template the diagnostic may not be valid for all instantiations. Therefore
the diagnostic is suppressed during the instantiation. Non dependent types
still issue a diagnostic.

The same can happen when using macros. Therefore the diagnostic is
disabled for macros.

Fixes https://bugs.llvm.org/show_bug.cgi?id=44556

Differential Revision: https://reviews.llvm.org/D73007

(cherry picked from commit 41fcd17250fa0526e4b7fd2c7df7721b0f79b683)

Added: 
    

Modified: 
    clang/lib/Sema/SemaStmt.cpp
    clang/test/SemaCXX/warn-range-loop-analysis.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index d6c3af9e84c8..ff6481006280 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2838,6 +2838,9 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef,
 ///    Suggest "const foo &x" to prevent the copy.
 static void DiagnoseForRangeVariableCopies(Sema &SemaRef,
                                            const CXXForRangeStmt *ForStmt) {
+  if (SemaRef.inTemplateInstantiation())
+    return;
+
   if (SemaRef.Diags.isIgnored(diag::warn_for_range_const_reference_copy,
                               ForStmt->getBeginLoc()) &&
       SemaRef.Diags.isIgnored(diag::warn_for_range_variable_always_copy,
@@ -2860,6 +2863,9 @@ static void DiagnoseForRangeVariableCopies(Sema &SemaRef,
   if (!InitExpr)
     return;
 
+  if (InitExpr->getExprLoc().isMacroID())
+    return;
+
   if (VariableType->isReferenceType()) {
     DiagnoseForRangeReferenceVariableCopies(SemaRef, VD,
                                             ForStmt->getRangeInit()->getType());

diff  --git a/clang/test/SemaCXX/warn-range-loop-analysis.cpp b/clang/test/SemaCXX/warn-range-loop-analysis.cpp
index 53b0ca288194..951844c953ef 100644
--- a/clang/test/SemaCXX/warn-range-loop-analysis.cpp
+++ b/clang/test/SemaCXX/warn-range-loop-analysis.cpp
@@ -454,3 +454,75 @@ void test10() {
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" "
 }
+
+template <class T>
+void test_template_function() {
+  // In a template instantiation the diagnostics should not be emitted for
+  // loops with dependent types.
+  Container<Bar> C;
+  for (const Bar &x : C) {}
+  // expected-warning at -1 {{always a copy}}
+  // expected-note at -2 {{'Bar'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
+
+  Container<T> Dependent;
+  for (const T &x : Dependent) {}
+}
+template void test_template_function<Bar>();
+
+template <class T>
+struct test_template_struct {
+  static void static_member() {
+    Container<Bar> C;
+    for (const Bar &x : C) {}
+    // expected-warning at -1 {{always a copy}}
+    // expected-note at -2 {{'Bar'}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
+
+    Container<T> Dependent;
+    for (const T &x : Dependent) {}
+  }
+
+  void member() {
+    Container<Bar> C;
+    for (const Bar &x : C) {}
+    // expected-warning at -1 {{always a copy}}
+    // expected-note at -2 {{'Bar'}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
+
+    Container<T> Dependent;
+    for (const T &x : Dependent) {}
+  }
+};
+template struct test_template_struct<Bar>;
+
+struct test_struct_with_templated_member {
+  void member() {
+    Container<Bar> C;
+    for (const Bar &x : C) {}
+    // expected-warning at -1 {{always a copy}}
+    // expected-note at -2 {{'Bar'}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
+  }
+
+  template <class T>
+  void template_member() {
+    Container<Bar> C;
+    for (const Bar &x : C) {}
+    // expected-warning at -1 {{always a copy}}
+    // expected-note at -2 {{'Bar'}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
+
+    Container<T> Dependent;
+    for (const T &x : Dependent) {}
+  }
+};
+template void test_struct_with_templated_member::template_member<Bar>();
+
+#define TEST_MACRO            \
+  void test_macro() {         \
+    Container<Bar> C;         \
+    for (const Bar &x : C) {} \
+  }
+
+TEST_MACRO


        


More information about the llvm-branch-commits mailing list