r205326 - [analyzer] Fix a CFG printing bug.

Jordan Rose jordan_rose at apple.com
Tue Apr 1 09:39:33 PDT 2014


Author: jrose
Date: Tue Apr  1 11:39:33 2014
New Revision: 205326

URL: http://llvm.org/viewvc/llvm-project?rev=205326&view=rev
Log:
[analyzer] Fix a CFG printing bug.

Also, add several destructor-related tests. Most of them don't work yet, but it's
good to have them recorded.

Patch by Alex McCarthy!

Added:
    cfe/trunk/test/Analysis/dtor-cxx11.cpp
Modified:
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/test/Analysis/dtor.cpp
    cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
    cfe/trunk/test/Analysis/temporaries.cpp
    cfe/trunk/test/SemaCXX/return-noreturn.cpp

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=205326&r1=205325&r2=205326&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Tue Apr  1 11:39:33 2014
@@ -3903,6 +3903,8 @@ static void print_block(raw_ostream &OS,
     OS << " (EXIT)]\n";
   else if (&B == cfg->getIndirectGotoBlock())
     OS << " (INDIRECT GOTO DISPATCH)]\n";
+  else if (B.hasNoReturnElement())
+    OS << " (NORETURN)]\n";
   else
     OS << "]\n";
   

Added: cfe/trunk/test/Analysis/dtor-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor-cxx11.cpp?rev=205326&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/dtor-cxx11.cpp (added)
+++ cfe/trunk/test/Analysis/dtor-cxx11.cpp Tue Apr  1 11:39:33 2014
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config cfg-temporary-dtors=true -Wno-null-dereference -verify %s
+// expected-no-diagnostics
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+namespace Cxx11BraceInit {
+  struct Foo {
+    ~Foo() {}
+  };
+
+  /* FIXME: Don't crash here.
+  void testInitializerList() {
+    for (Foo foo : {Foo(), Foo()}) {}
+  } */
+}

Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=205326&r1=205325&r2=205326&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Tue Apr  1 11:39:33 2014
@@ -374,6 +374,64 @@ namespace LifetimeExtension {
     clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}}
   }
 
+  struct NRCheck {
+    bool bool_;
+    NRCheck():bool_(true) {}
+    ~NRCheck() __attribute__((noreturn));
+    operator bool() const { return bool_; }
+  };
+
+  struct CheckAutoDestructor {
+    bool bool_;
+    CheckAutoDestructor():bool_(true) {}
+    operator bool() const { return bool_; }
+  };
+
+  struct CheckCustomDestructor {
+    bool bool_;
+    CheckCustomDestructor():bool_(true) {}
+    ~CheckCustomDestructor();
+    operator bool() const { return bool_; }
+  };
+
+  bool testUnnamedNR() {
+    if (NRCheck())
+      return true;
+    return false;
+  }
+
+  bool testNamedNR() {
+    if (NRCheck c = NRCheck())
+      return true;
+    return false;
+  }
+
+  bool testUnnamedAutoDestructor() {
+    if (CheckAutoDestructor())
+      return true;
+    return false;
+  }
+
+  bool testNamedAutoDestructor() {
+    if (CheckAutoDestructor c = CheckAutoDestructor())
+      return true;
+    return false;
+  }
+
+  bool testUnnamedCustomDestructor() {
+    if (CheckCustomDestructor())
+      return true;
+    return false;
+  }
+
+  // This case used to cause an unexpected "Undefined or garbage value returned
+  // to caller" warning
+  bool testNamedCustomDestructor() {
+    if (CheckCustomDestructor c = CheckCustomDestructor())
+      return true;
+    return false;
+  }
+
   class VirtualDtorBase {
   public:
     int value;
@@ -416,6 +474,12 @@ namespace NoReturn {
     f(&x);
     *x = 47; // no warning
   }
+
+  void g2(int *x) {
+    if (! x) NR();
+    // FIXME: this shouldn't cause a warning.
+    *x = 47; // expected-warning{{Dereference of null pointer}}
+  }
 }
 
 namespace PseudoDtor {

Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=205326&r1=205325&r2=205326&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Tue Apr  1 11:39:33 2014
@@ -51,6 +51,37 @@ void test_cond() {
   int b;
 }
 
+struct C {
+  C():b_(true) {}
+  ~C() {}
+
+  operator bool() { return b_; }
+  bool b_;
+};
+
+struct D {
+  D():b_(true) {}
+
+  operator bool() { return b_; }
+  bool b_;
+};
+
+int test_cond_unnamed_custom_destructor() {
+  if (C()) { return 1; } else { return 0; }
+}
+
+int test_cond_named_custom_destructor() {
+  if (C c = C()) { return 1; } else { return 0; }
+}
+
+int test_cond_unnamed_auto_destructor() {
+  if (D()) { return 1; } else { return 0; }
+}
+
+int test_cond_named_auto_destructor() {
+  if (D d = D()) { return 1; } else { return 0; }
+}
+
 void test_cond_cref() {
   const A& a = B() ? A() : A(B());
   foo(B() ? A() : A(B()));
@@ -125,6 +156,38 @@ void test_noreturn2() {
   int b;
 }
 
+extern bool check(const NoReturn&);
+
+// PR16664 and PR18159
+int testConsistencyNestedSimple(bool value) {
+  if (value) {
+    if (!value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+// PR16664 and PR18159
+int testConsistencyNestedComplex(bool value) {
+  if (value) {
+    if (!value || !value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+// PR16664 and PR18159
+int testConsistencyNestedNormalReturn(bool value) {
+  if (value) {
+    if (!value || value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
 // CHECK:   [B1 (ENTRY)]
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
@@ -470,6 +533,166 @@ void test_noreturn2() {
 // CHECK:     Succs (2): B8 B9
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (1): B1
+// CHECK:  C() : b_(true)
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: true
+// CHECK:     2: b_([B1.1]) (Member initializer)
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  ~C()
+// CHECK:   [B1 (ENTRY)]
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  operator bool()
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: this
+// CHECK:     2: [B1.1]->b_
+// CHECK:     3: [B1.2] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     4: return [B1.3];
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  D() : b_(true)
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: true
+// CHECK:     2: b_([B1.1]) (Member initializer)
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  operator bool()
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: this
+// CHECK:     2: [B1.1]->b_
+// CHECK:     3: [B1.2] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     4: return [B1.3];
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  int test_cond_unnamed_custom_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: C() (CXXConstructExpr, struct C)
+// CHECK:     2: [B3.1] (BindTemporary)
+// CHECK:     3: [B3.2].operator bool
+// CHECK:     4: [B3.2]
+// CHECK:     5: [B3.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     6: ~C() (Temporary object destructor)
+// CHECK:     T: if [B3.5]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
+// CHECK:  int test_cond_named_custom_destructor()
+// CHECK:   [B5 (ENTRY)]
+// CHECK:     Succs (1): B4
+// CHECK:   [B1]
+// CHECK:     1: [B4.7].~C() (Implicit destructor)
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 0
+// CHECK:     2: return [B2.1];
+// CHECK:     3: [B4.7].~C() (Implicit destructor)
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: 1
+// CHECK:     2: return [B3.1];
+// CHECK:     3: [B4.7].~C() (Implicit destructor)
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (1): B0
+// CHECK:   [B4]
+// CHECK:     1: C() (CXXConstructExpr, struct C)
+// CHECK:     2: [B4.1] (BindTemporary)
+// CHECK:     3: [B4.2] (ImplicitCastExpr, NoOp, const struct C)
+// CHECK:     4: [B4.3]
+// CHECK:     5: [B4.4] (CXXConstructExpr, struct C)
+// CHECK:     6: ~C() (Temporary object destructor)
+// CHECK:     7: C c = C();
+// CHECK:     8: c
+// CHECK:     9: [B4.8].operator bool
+// CHECK:    10: [B4.8]
+// CHECK:    11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B4.11]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B3 B2
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B3
+// CHECK:  int test_cond_unnamed_auto_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: D() (CXXConstructExpr, struct D)
+// CHECK:     2: [B3.1].operator bool
+// CHECK:     3: [B3.1]
+// CHECK:     4: [B3.3] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B3.4]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
+// CHECK:  int test_cond_named_auto_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: D() (CXXConstructExpr, struct D)
+// CHECK:     2: [B3.1] (ImplicitCastExpr, NoOp, const struct D)
+// CHECK:     3: [B3.2]
+// CHECK:     4: [B3.3] (CXXConstructExpr, struct D)
+// CHECK:     5: D d = D();
+// CHECK:     6: d
+// CHECK:     7: [B3.6].operator bool
+// CHECK:     8: [B3.6]
+// CHECK:     9: [B3.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B3.9]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
 // CHECK:   [B14 (ENTRY)]
 // CHECK:     Succs (1): B13
 // CHECK:   [B1]
@@ -867,7 +1090,7 @@ void test_noreturn2() {
 // CHECK:   [B1]
 // CHECK:     1: int b;
 // CHECK:     Succs (1): B0
-// CHECK:   [B2]
+// CHECK:   [B2 (NORETURN)]
 // CHECK:     1: int a;
 // CHECK:     2: NoReturn() (CXXConstructExpr, class NoReturn)
 // CHECK:     3: [B2.2] (BindTemporary)
@@ -883,7 +1106,7 @@ void test_noreturn2() {
 // CHECK:   [B1]
 // CHECK:     1: int b;
 // CHECK:     Succs (1): B0
-// CHECK:   [B2]
+// CHECK:   [B2 (NORETURN)]
 // CHECK:     1: int a;
 // CHECK:     2: NoReturn() (CXXConstructExpr, class NoReturn)
 // CHECK:     3: [B2.2] (BindTemporary)
@@ -894,3 +1117,169 @@ void test_noreturn2() {
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (2): B1 B2
+// CHECK:  int testConsistencyNestedSimple(bool value)
+// CHECK:   [B9 (ENTRY)]
+// CHECK:     Succs (1): B8
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B8
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B7.3] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B7.3] || ...
+// CHECK:     Preds (2): B6 B7
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B7.2]
+// CHECK:     T: [B7.3] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B8.2]
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B7 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4
+// CHECK:  int testConsistencyNestedComplex(bool value)
+// CHECK:   [B10 (ENTRY)]
+// CHECK:     Succs (1): B9
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B9
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B8.3] || [B7.3] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B8.3] || [B7.3] || ...
+// CHECK:     Preds (3): B6 B7 B8
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B7.2]
+// CHECK:     T: [B8.3] || [B7.3] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B8.2]
+// CHECK:     T: [B8.3] || ...
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B5 B7
+// CHECK:   [B9]
+// CHECK:     1: value
+// CHECK:     2: [B9.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B9.2]
+// CHECK:     Preds (1): B10
+// CHECK:     Succs (2): B8 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4
+// CHECK:  int testConsistencyNestedNormalReturn(bool value)
+// CHECK:   [B10 (ENTRY)]
+// CHECK:     Succs (1): B9
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B9
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B8.3] || [B7.2] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B8.3] || [B7.2] || ...
+// CHECK:     Preds (3): B6 B7 B8
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: [B8.3] || [B7.2] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B8.2]
+// CHECK:     T: [B8.3] || ...
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B5 B7
+// CHECK:   [B9]
+// CHECK:     1: value
+// CHECK:     2: [B9.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B9.2]
+// CHECK:     Preds (1): B10
+// CHECK:     Succs (2): B8 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4

Modified: cfe/trunk/test/Analysis/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=205326&r1=205325&r2=205326&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temporaries.cpp (original)
+++ cfe/trunk/test/Analysis/temporaries.cpp Tue Apr  1 11:39:33 2014
@@ -119,8 +119,8 @@ namespace destructors {
     extern bool check(const Dtor &);
 
 #ifndef TEMPORARY_DTORS
-    // FIXME: Don't crash here when tmp dtros are enabled.
-    // PR16664 and PR18159 
+    // FIXME: Don't assert here when tmp dtors are enabled.
+    // PR16664 and PR18159
     if (coin() && (coin() || coin() || check(Dtor()))) {
       Dtor();
     }
@@ -170,10 +170,9 @@ namespace destructors {
     clang_analyzer_eval(true); // no warning, unreachable code
   }
 
-
 /*
-  // PR16664 and PR18159 
-  FIXME: Don't crash here.
+  // PR16664 and PR18159
+  FIXME: Don't assert here.
   void testConsistencyNested(int i) {
     extern bool compute(bool);
   
@@ -193,6 +192,7 @@ namespace destructors {
       clang_analyzer_eval(true); // expected TRUE
     }
 
+    FIXME: This shouldn't cause a warning.
     if (compute(i == 5 &&
                 (i == 4 || i == 4 ||
                  compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) ||
@@ -200,7 +200,35 @@ namespace destructors {
       clang_analyzer_eval(true); // no warning, unreachable code
     }
   }*/
-  
+
+  // PR16664 and PR18159
+  void testConsistencyNestedSimple(bool value) {
+    if (value) {
+      if (!value || check(NoReturnDtor())) {
+        clang_analyzer_eval(true); // no warning, unreachable code
+      }
+    }
+  }
+
+  // PR16664 and PR18159
+  void testConsistencyNestedComplex(bool value) {
+    if (value) {
+      if (!value || !value || check(NoReturnDtor())) {
+        // FIXME: This shouldn't cause a warning.
+        clang_analyzer_eval(true); // expected-warning{{TRUE}}
+      }
+    }
+  }
+
+  // PR16664 and PR18159
+  void testConsistencyNestedWarning(bool value) {
+    if (value) {
+      if (!value || value || check(NoReturnDtor())) {
+        clang_analyzer_eval(true); // expected-warning{{TRUE}}
+      }
+    }
+  }
+
 #endif // TEMPORARY_DTORS
 }
 

Modified: cfe/trunk/test/SemaCXX/return-noreturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return-noreturn.cpp?rev=205326&r1=205325&r2=205326&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/return-noreturn.cpp (original)
+++ cfe/trunk/test/SemaCXX/return-noreturn.cpp Tue Apr  1 11:39:33 2014
@@ -40,6 +40,14 @@ namespace abort_struct_complex_cfgs {
     switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
   }
 
+  // FIXME: detect noreturn destructors triggered by calls to delete.
+  int f7(int x) {
+    switch (x) default: L1: L2: case 4: {
+      pr6884_abort_struct *p = new pr6884_abort_struct();
+      delete p;
+    }
+  } // expected-warning {{control reaches end of non-void function}}
+
   // Test that these constructs work even when extraneous blocks are created
   // before and after the switch due to implicit destructors.
   int g1(int x) {





More information about the cfe-commits mailing list