Enhance Sema::DiagRuntimeBehavior() to delay some diagnostics to see if the related code is reachable.  This suppresses some
diagnostics that occur in unreachable code (e.g., -Warray-bound).

We only pay the cost of doing the reachability analysis when we issue one of these diagnostics.

llvm-svn: 126290
diff --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp
index 0286c01..ee7882d 100644
--- a/clang/test/SemaCXX/array-bounds.cpp
+++ b/clang/test/SemaCXX/array-bounds.cpp
@@ -63,11 +63,11 @@
 }
 
 template <int I> struct S {
-  char arr[I]; // expected-note 3 {{declared here}}
+  char arr[I]; // expected-note 2 {{declared here}}
 };
 template <int I> void f() {
   S<3> s;
-  s.arr[4] = 0; // expected-warning 2 {{array index of '4' indexes past the end of an array (that contains 3 elements)}}
+  s.arr[4] = 0; // expected-warning {{array index of '4' indexes past the end of an array (that contains 3 elements)}}
   s.arr[I] = 0; // expected-warning {{array index of '5' indexes past the end of an array (that contains 3 elements)}}
 }
 
@@ -79,9 +79,8 @@
 #define ARR_IN_MACRO(flag, arr, idx) flag ? arr[idx] : 1
 
 int test_no_warn_macro_unreachable() {
-  int arr[SIZE]; // expected-note 2 {{array 'arr' declared here}}
-  // FIXME: We don't want to warn for the first case.
-  return ARR_IN_MACRO(0, arr, SIZE) + // expected-warning{{array index of '10' indexes past the end of an array (that contains 10 elements)}}
+  int arr[SIZE]; // expected-note {{array 'arr' declared here}}
+  return ARR_IN_MACRO(0, arr, SIZE) + // no-warning
          ARR_IN_MACRO(1, arr, SIZE); // expected-warning{{array index of '10' indexes past the end of an array (that contains 10 elements)}}
 }
 
@@ -91,3 +90,15 @@
   return array[(unsigned long long) 100]; // expected-warning {{array index of '100' indexes past the end of an array (that contains 100 elements)}}
 }
 
+template <bool extendArray>
+void myFunc() {
+    int arr[3 + (extendArray ? 1 : 0)];
+
+    if (extendArray)
+        arr[3] = 42;
+}
+
+void f() {
+    myFunc<false>();
+}
+