Re: [PATCH] D23898: Minor cleanup of MismatchingNewDeleteDetector
ismailp accepted this revision. ismailp added a comment. LGTM, thanks! Repository: rL LLVM https://reviews.llvm.org/D23898 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24158: Try contextually converting condition of constexpr if to Boolean value
ismailp created this revision. ismailp added a reviewer: rsmith. ismailp added a subscriber: cfe-commits. C++1z 6.4.1/p2: If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool [...] C++1z 5.20/p4: [...] A contextually converted constant expression of type bool is an expression, contextually converted to bool (Clause4), where the converted expression is a constant expression and the conversion sequence contains only the conversions above. [...] Contextually converting result of an expression `e` to a Boolean value requires `bool t(e)` to be well-formed. An explicit conversion function is only considered as a user-defined conversion for direct-initialization, which is essentially what //contextually converted to bool// requires. Also, fixes PR28470. https://reviews.llvm.org/D24158 Files: lib/Sema/SemaOverload.cpp test/CodeGenCXX/cxx1z-constexpr-if.cpp Index: test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5140,12 +5140,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Index: test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5140,12 +5140,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, +
Re: [PATCH] D24158: Try contextually converting condition of constexpr if to Boolean value
ismailp updated this revision to Diff 70561. ismailp added a comment. - Added more tests https://reviews.llvm.org/D24158 Files: lib/Sema/SemaOverload.cpp test/CodeGenCXX/cxx1z-constexpr-if.cpp Index: test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -1,8 +1,17 @@ // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used +// RUN: %clang_cc1 -std=c++1z %s -DCHECK_CONVERSION -verify %s void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +24,17 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); +#ifdef CHECK_CONVERSION + if constexpr (4.3) ; // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} + constexpr void *p = nullptr; + if constexpr (p) ; // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} +#endif } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5140,12 +5140,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Index: test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -1,8 +1,17 @@ // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used +// RUN: %clang_cc1 -std=c++1z %s -DCHECK_CONVERSION -verify %s void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +24,17 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); +#ifdef CHECK_CONVERSION + if constexpr (4.3) ; // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} + constexpr void *p = nullptr; + if constexpr (p) ; // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} +#endif } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5140,12 +5140,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyC
Re: [PATCH] D24158: Try contextually converting condition of constexpr if to Boolean value
ismailp added a comment. Thank you for reviewing. Sure, I'll try to look into those conversions as well. Comment at: test/CodeGenCXX/cxx1z-constexpr-if.cpp:2 @@ -1,2 +1,3 @@ // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used +// RUN: %clang_cc1 -std=c++1z %s -DCHECK_CONVERSION -verify %s Is there a more elegant way to do this? The previous check didn't seem to work with diagnostics. https://reviews.llvm.org/D24158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r280838 - Try contextually converting condition of constexpr if to Boolean value
Author: ismailp Date: Wed Sep 7 13:24:54 2016 New Revision: 280838 URL: http://llvm.org/viewvc/llvm-project?rev=280838&view=rev Log: Try contextually converting condition of constexpr if to Boolean value Summary: C++1z 6.4.1/p2: If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool [...] C++1z 5.20/p4: [...] A contextually converted constant expression of type bool is an expression, contextually converted to bool (Clause4), where the converted expression is a constant expression and the conversion sequence contains only the conversions above. [...] Contextually converting result of an expression `e` to a Boolean value requires `bool t(e)` to be well-formed. An explicit conversion function is only considered as a user-defined conversion for direct-initialization, which is essentially what //contextually converted to bool// requires. Also, fixes PR28470. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D24158 Modified: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=280838&r1=280837&r2=280838&view=diff == --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Sep 7 13:24:54 2016 @@ -5164,12 +5164,18 @@ static ExprResult CheckConvertedConstant // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp?rev=280838&r1=280837&r2=280838&view=diff == --- cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp (original) +++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp Wed Sep 7 13:24:54 2016 @@ -46,6 +46,11 @@ namespace ccce { if constexpr (N) {} // expected-error {{cannot be narrowed}} } template void g<5>(); // expected-note {{instantiation of}} + void h() { +if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} +constexpr void *p = nullptr; +if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} + } } namespace generic_lambda { Modified: cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp?rev=280838&r1=280837&r2=280838&view=diff == --- cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp (original) +++ cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp Wed Sep 7 13:24:54 2016 @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ void f() { goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24158: Try contextually converting condition of constexpr if to Boolean value
This revision was automatically updated to reflect the committed changes. Closed by commit rL280838: Try contextually converting condition of constexpr if to Boolean value (authored by ismailp). Changed prior to commit: https://reviews.llvm.org/D24158?vs=70561&id=70577#toc Repository: rL LLVM https://reviews.llvm.org/D24158 Files: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp Index: cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp === --- cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp +++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp @@ -46,6 +46,11 @@ if constexpr (N) {} // expected-error {{cannot be narrowed}} } template void g<5>(); // expected-note {{instantiation of}} + void h() { +if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} +constexpr void *p = nullptr; +if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} + } } namespace generic_lambda { Index: cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: cfe/trunk/lib/Sema/SemaOverload.cpp === --- cfe/trunk/lib/Sema/SemaOverload.cpp +++ cfe/trunk/lib/Sema/SemaOverload.cpp @@ -5164,12 +5164,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = -TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Index: cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp === --- cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp +++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp @@ -46,6 +46,11 @@ if constexpr (N) {} // expected-error {{cannot be narrowed}} } template void g<5>(); // expected-note {{instantiation of}} + void h() { +if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} +constexpr void *p = nullptr; +if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} + } } namespace generic_lambda { Index: cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp === --- cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -2,7 +2,15 @@ void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { +return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +23,12 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) +should_be_used_3(); + else +should_not_be_used(); } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3 Index: cfe/trunk/lib/Sema/SemaOverload.cpp
Re: [PATCH] D24158: Try contextually converting condition of constexpr if to Boolean value
ismailp added inline comments. Comment at: test/CodeGenCXX/cxx1z-constexpr-if.cpp:2 @@ -1,2 +1,3 @@ // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used +// RUN: %clang_cc1 -std=c++1z %s -DCHECK_CONVERSION -verify %s rsmith wrote: > ismailp wrote: > > Is there a more elegant way to do this? The previous check didn't seem to > > work with diagnostics. > Tests for semantic issues should go into test/SemaCXX (organized by category) > or test/CXX (organized by section of the standard). In this case, > test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp is probably the most > appropriate place (somewhere in its `namespace ccce`, perhaps). Thanks! I've done that, and pushed. Repository: rL LLVM https://reviews.llvm.org/D24158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12251: Analyzer: Calculate field offset correctly
ismailp added a comment. Ping! http://reviews.llvm.org/D12251 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added a comment. I don't have ubigraph installed either. The purpose of the test isn't to check as to whether we can generate a conforming/sensible ubigraph output, but to ensure that this tiny patch works and clang doesn't crash. So, I'd keep it. But if you are worried about other/unknown problems in ubigraph generator that the test might surface, then we can proceed without the test, and a ubigraph expert can write an output validation test. http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp updated this revision to Diff 35141. ismailp added a comment. - Added a new test file instead of adding '-analyzer-viz-egraph-ubigraph' to an existing test. http://reviews.llvm.org/D12119 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/ubigraph-viz.cpp Index: test/Analysis/ubigraph-viz.cpp === --- /dev/null +++ test/Analysis/ubigraph-viz.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s +// expected-no-diagnostics + +int f(int x) { + return x < 0 ? 0 : 42; +} + Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Index: test/Analysis/ubigraph-viz.cpp === --- /dev/null +++ test/Analysis/ubigraph-viz.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s +// expected-no-diagnostics + +int f(int x) { + return x < 0 ? 0 : 42; +} + Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r248050 - Analyzer: Fix a crasher in UbigraphViz
Author: ismailp Date: Fri Sep 18 16:54:47 2015 New Revision: 248050 URL: http://llvm.org/viewvc/llvm-project?rev=248050&view=rev Log: Analyzer: Fix a crasher in UbigraphViz Summary: Name `Out` refers to the parameter. It is moved into the member `Out` in ctor-init. Dereferencing null pointer will crash clang, if user passes '-analyzer-viz-egraph-ubigraph' argument. Reviewers: zaks.anna, krememek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D12119 Added: cfe/trunk/test/Analysis/ubigraph-viz.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=248050&r1=248049&r2=248050&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Sep 18 16:54:47 2015 @@ -778,8 +778,9 @@ void UbigraphViz::AddEdge(ExplodedNode * << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Added: cfe/trunk/test/Analysis/ubigraph-viz.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ubigraph-viz.cpp?rev=248050&view=auto == --- cfe/trunk/test/Analysis/ubigraph-viz.cpp (added) +++ cfe/trunk/test/Analysis/ubigraph-viz.cpp Fri Sep 18 16:54:47 2015 @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s +// expected-no-diagnostics + +int f(int x) { + return x < 0 ? 0 : 42; +} + ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
This revision was automatically updated to reflect the committed changes. Closed by commit rL248050: Analyzer: Fix a crasher in UbigraphViz (authored by ismailp). Changed prior to commit: http://reviews.llvm.org/D12119?vs=35141&id=35142#toc Repository: rL LLVM http://reviews.llvm.org/D12119 Files: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp cfe/trunk/test/Analysis/ubigraph-viz.cpp Index: cfe/trunk/test/Analysis/ubigraph-viz.cpp === --- cfe/trunk/test/Analysis/ubigraph-viz.cpp +++ cfe/trunk/test/Analysis/ubigraph-viz.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s +// expected-no-diagnostics + +int f(int x) { + return x < 0 ? 0 : 42; +} + Index: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Index: cfe/trunk/test/Analysis/ubigraph-viz.cpp === --- cfe/trunk/test/Analysis/ubigraph-viz.cpp +++ cfe/trunk/test/Analysis/ubigraph-viz.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s +// expected-no-diagnostics + +int f(int x) { + return x < 0 ? 0 : 42; +} + Index: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added a comment. Thank you for reviewing! Repository: rL LLVM http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D9898: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
ismailp added a reviewer: majnemer. ismailp marked an inline comment as done. ismailp added a comment. Ping! http://reviews.llvm.org/D9898 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
ismailp added a comment. Ping! http://reviews.llvm.org/D12482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
ismailp added a comment. Sorry, that's a typo. It is 24170. http://reviews.llvm.org/D12482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
ismailp updated this revision to Diff 35384. ismailp added a comment. Addressed comments. http://reviews.llvm.org/D12482 Files: lib/StaticAnalyzer/Core/Environment.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/SValBuilder.cpp test/Analysis/dtor.cpp Index: test/Analysis/dtor.cpp === --- test/Analysis/dtor.cpp +++ test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -505,3 +505,38 @@ class Foo; // expected-note{{forward declaration}} void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}} } + +namespace TypeTraitExpr { +template +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsSimple = __is_trivial(T) && __is_same(T, U); + copier::do_copy(dest, src, count); +} +struct NonTrivial { + int *p; + NonTrivial() : p(new int[1]) { p[0] = 0; } + NonTrivial(const NonTrivial &other) { +p = new int[1]; +do_copy(p, other.p, 1); + } + NonTrivial &operator=(const NonTrivial &other) { +p = other.p; +return *this; + } + ~NonTrivial() { +delete[] p; // expected-warning {{free released memory}} + } +}; + +void f() { + NonTrivial nt1; + NonTrivial nt2(nt1); + nt1 = nt2; + clang_analyzer_eval(__is_trivial(NonTrivial)); // expected-warning{{FALSE}} + clang_analyzer_eval(__alignof(NonTrivial) > 0); // expected-warning{{TRUE}} +} +} Index: lib/StaticAnalyzer/Core/SValBuilder.cpp === --- lib/StaticAnalyzer/Core/SValBuilder.cpp +++ lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -259,6 +259,11 @@ case Stmt::CXXBoolLiteralExprClass: return makeBoolVal(cast(E)); + case Stmt::TypeTraitExprClass: { +const TypeTraitExpr *TE = cast(E); +return makeTruthVal(TE->getValue(), TE->getType()); + } + case Stmt::IntegerLiteralClass: return makeIntVal(cast(E)); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp === --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -756,7 +756,6 @@ case Stmt::MSPropertyRefExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::DependentScopeDeclRefExprClass: -case Stmt::TypeTraitExprClass: case Stmt::ArrayTypeTraitExprClass: case Stmt::ExpressionTraitExprClass: case Stmt::UnresolvedLookupExprClass: @@ -902,7 +901,8 @@ case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: -case Stmt::OMPArraySectionExprClass: { +case Stmt::OMPArraySectionExprClass: +case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); Index: lib/StaticAnalyzer/Core/Environment.cpp === --- lib/StaticAnalyzer/Core/Environment.cpp +++ lib/StaticAnalyzer/Core/Environment.cpp @@ -90,6 +90,7 @@ case Stmt::CXXNullPtrLiteralExprClass: case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: + case Stmt::TypeTraitExprClass: // Known constants; defer to SValBuilder. return svalBuilder.getConstantVal(cast(S)).getValue(); Index: test/Analysis/dtor.cpp === --- test/Analysis/dtor.cpp +++ test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -505,3 +505,38 @@ class Foo; // expected-note{{forward declaration}} void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}} } + +namespace TypeTraitExpr { +template +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsS
Re: [PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
ismailp marked an inline comment as done. ismailp added a comment. Thanks for reviewing. http://reviews.llvm.org/D12482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r248314 - Analyzer: Teach analyzer how to handle TypeTraitExpr
Author: ismailp Date: Tue Sep 22 14:33:15 2015 New Revision: 248314 URL: http://llvm.org/viewvc/llvm-project?rev=248314&view=rev Log: Analyzer: Teach analyzer how to handle TypeTraitExpr Summary: `TypeTraitExpr`s are not supported by the ExprEngine today. Analyzer creates a sink, and aborts the block. Therefore, certain bugs that involve type traits intrinsics cannot be detected (see PR24710). This patch creates boolean `SVal`s for `TypeTraitExpr`s, which are evaluated by the compiler. Test within the patch is a summary of PR24710. Reviewers: zaks.anna, dcoughlin, krememek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D12482 Modified: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp cfe/trunk/test/Analysis/dtor.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp?rev=248314&r1=248313&r2=248314&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp Tue Sep 22 14:33:15 2015 @@ -90,6 +90,7 @@ SVal Environment::getSVal(const Environm case Stmt::CXXNullPtrLiteralExprClass: case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: + case Stmt::TypeTraitExprClass: // Known constants; defer to SValBuilder. return svalBuilder.getConstantVal(cast(S)).getValue(); Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=248314&r1=248313&r2=248314&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Sep 22 14:33:15 2015 @@ -756,7 +756,6 @@ void ExprEngine::Visit(const Stmt *S, Ex case Stmt::MSPropertyRefExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::DependentScopeDeclRefExprClass: -case Stmt::TypeTraitExprClass: case Stmt::ArrayTypeTraitExprClass: case Stmt::ExpressionTraitExprClass: case Stmt::UnresolvedLookupExprClass: @@ -902,7 +901,8 @@ void ExprEngine::Visit(const Stmt *S, Ex case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: -case Stmt::OMPArraySectionExprClass: { +case Stmt::OMPArraySectionExprClass: +case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=248314&r1=248313&r2=248314&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Tue Sep 22 14:33:15 2015 @@ -259,6 +259,11 @@ Optional SValBuilder::getConstantV case Stmt::CXXBoolLiteralExprClass: return makeBoolVal(cast(E)); + case Stmt::TypeTraitExprClass: { +const TypeTraitExpr *TE = cast(E); +return makeTruthVal(TE->getValue(), TE->getType()); + } + case Stmt::IntegerLiteralClass: return makeIntVal(cast(E)); Modified: cfe/trunk/test/Analysis/dtor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=248314&r1=248313&r2=248314&view=diff == --- cfe/trunk/test/Analysis/dtor.cpp (original) +++ cfe/trunk/test/Analysis/dtor.cpp Tue Sep 22 14:33:15 2015 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -505,3 +505,38 @@ namespace Incomplete { class Foo; // expected-note{{forward declaration}} void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}} } + +namespace TypeTraitExpr { +template +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsSimple = __is_trivial(T) && __is_same(T, U); + copier::do_copy(dest, src, count); +} +struct NonTrivial { + int *p; +
Re: [PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
This revision was automatically updated to reflect the committed changes. Closed by commit rL248314: Analyzer: Teach analyzer how to handle TypeTraitExpr (authored by ismailp). Changed prior to commit: http://reviews.llvm.org/D12482?vs=35384&id=35403#toc Repository: rL LLVM http://reviews.llvm.org/D12482 Files: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp cfe/trunk/test/Analysis/dtor.cpp Index: cfe/trunk/test/Analysis/dtor.cpp === --- cfe/trunk/test/Analysis/dtor.cpp +++ cfe/trunk/test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -505,3 +505,38 @@ class Foo; // expected-note{{forward declaration}} void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}} } + +namespace TypeTraitExpr { +template +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsSimple = __is_trivial(T) && __is_same(T, U); + copier::do_copy(dest, src, count); +} +struct NonTrivial { + int *p; + NonTrivial() : p(new int[1]) { p[0] = 0; } + NonTrivial(const NonTrivial &other) { +p = new int[1]; +do_copy(p, other.p, 1); + } + NonTrivial &operator=(const NonTrivial &other) { +p = other.p; +return *this; + } + ~NonTrivial() { +delete[] p; // expected-warning {{free released memory}} + } +}; + +void f() { + NonTrivial nt1; + NonTrivial nt2(nt1); + nt1 = nt2; + clang_analyzer_eval(__is_trivial(NonTrivial)); // expected-warning{{FALSE}} + clang_analyzer_eval(__alignof(NonTrivial) > 0); // expected-warning{{TRUE}} +} +} Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -756,7 +756,6 @@ case Stmt::MSPropertyRefExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::DependentScopeDeclRefExprClass: -case Stmt::TypeTraitExprClass: case Stmt::ArrayTypeTraitExprClass: case Stmt::ExpressionTraitExprClass: case Stmt::UnresolvedLookupExprClass: @@ -902,7 +901,8 @@ case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: -case Stmt::OMPArraySectionExprClass: { +case Stmt::OMPArraySectionExprClass: +case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); Index: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -259,6 +259,11 @@ case Stmt::CXXBoolLiteralExprClass: return makeBoolVal(cast(E)); + case Stmt::TypeTraitExprClass: { +const TypeTraitExpr *TE = cast(E); +return makeTruthVal(TE->getValue(), TE->getType()); + } + case Stmt::IntegerLiteralClass: return makeIntVal(cast(E)); Index: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp @@ -90,6 +90,7 @@ case Stmt::CXXNullPtrLiteralExprClass: case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: + case Stmt::TypeTraitExprClass: // Known constants; defer to SValBuilder. return svalBuilder.getConstantVal(cast(S)).getValue(); Index: cfe/trunk/test/Analysis/dtor.cpp === --- cfe/trunk/test/Analysis/dtor.cpp +++ cfe/trunk/test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool);
Re: [PATCH] D12251: Analyzer: Calculate field offset correctly
ismailp added a comment. Ping! http://reviews.llvm.org/D12251 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12251: Analyzer: Calculate field offset correctly
ismailp updated this revision to Diff 36123. ismailp added a comment. - Don't try to calculate field offset for Objective-C instance variables - Added test for Objective-C instance variables - Added a non-null pointer in test http://reviews.llvm.org/D12251 Files: lib/StaticAnalyzer/Core/Store.cpp test/Analysis/array-struct-region.cpp test/Analysis/ivars.m Index: test/Analysis/ivars.m === --- test/Analysis/ivars.m +++ test/Analysis/ivars.m @@ -138,3 +138,8 @@ int *x = &obj->uniqueID; return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} } + +void testFieldOffset() { + int *v = &((Root *)0x10)->uniqueID; + (void)v; +} Index: test/Analysis/array-struct-region.cpp === --- test/Analysis/array-struct-region.cpp +++ test/Analysis/array-struct-region.cpp @@ -106,6 +106,28 @@ #endif } +struct FieldOffset { + int firstField; + char secondField[63]; + void *thirdField; +}; + +void testFieldOffsets() { + struct FieldOffset FO; + struct FieldOffset *PFONull = 0; + struct FieldOffset *PFOConstant = (struct FieldOffset *) 0x22; +#if __cplusplus + struct FieldOffset *PFONew = new struct FieldOffset; +#endif + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO.thirdField); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFONull->secondField != (void *)&PFONull->thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)&PFONull->secondField == (void *)0); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFOConstant->secondField != (void*)PFOConstant); // expected-warning{{TRUE}} +#if __cplusplus + clang_analyzer_eval((void *)&PFONew->secondField != (void *)&PFONew); // expected-warning{{TRUE}} +#endif +} // // C++-only tests Index: lib/StaticAnalyzer/Core/Store.cpp === --- lib/StaticAnalyzer/Core/Store.cpp +++ lib/StaticAnalyzer/Core/Store.cpp @@ -15,6 +15,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" @@ -401,12 +402,23 @@ // These are anormal cases. Flag an undefined value. return UndefinedVal(); - case loc::ConcreteIntKind: -// While these seem funny, this can happen through casts. -// FIXME: What we should return is the field offset. For example, -// add the field offset to the integer value. That way funny things -// like this work properly: &(((struct foo *) 0xa)->f) + case loc::ConcreteIntKind: { +// Don't allow field offset calculations, if base is null. +if (!Base.isZeroConstant()) { + if (const auto *FD = dyn_cast(D)) { +if (FD->getKind() != Decl::ObjCIvar) { + ASTContext &Ctx = D->getASTContext(); + CharUnits CU = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FD)); + loc::ConcreteInt BasePtr = BaseL.castAs(); + llvm::APSInt Offset(Ctx.getTypeSize(Ctx.VoidPtrTy)); + Offset = CU.getQuantity(); + Offset += BasePtr.getValue(); + return svalBuilder.makeIntLocVal(Offset); +} + } +} return Base; + } default: llvm_unreachable("Unhandled Base."); Index: test/Analysis/ivars.m === --- test/Analysis/ivars.m +++ test/Analysis/ivars.m @@ -138,3 +138,8 @@ int *x = &obj->uniqueID; return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} } + +void testFieldOffset() { + int *v = &((Root *)0x10)->uniqueID; + (void)v; +} Index: test/Analysis/array-struct-region.cpp === --- test/Analysis/array-struct-region.cpp +++ test/Analysis/array-struct-region.cpp @@ -106,6 +106,28 @@ #endif } +struct FieldOffset { + int firstField; + char secondField[63]; + void *thirdField; +}; + +void testFieldOffsets() { + struct FieldOffset FO; + struct FieldOffset *PFONull = 0; + struct FieldOffset *PFOConstant = (struct FieldOffset *) 0x22; +#if __cplusplus + struct FieldOffset *PFONew = new struct FieldOffset; +#endif + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO.thirdField); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFONull->secondField != (void *)&PFONull->thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)&PFONull->secondField == (void *)0); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFOConstant-
Re: [PATCH] D12251: Analyzer: Calculate field offset correctly
ismailp marked 3 inline comments as done. Comment at: test/Analysis/array-struct-region.cpp:128 @@ +127,3 @@ +#if __cplusplus + clang_analyzer_eval((void *)&PFONew->secondField != (void *)&PFONew); // expected-warning{{TRUE}} +#endif I might be missing something, and would be very happy if you could explain why it is necessary to add `PFOConstant`. At line 122, for example, where `&FO` is always non-null. Likewise, I'd expect line 128 to be non-null, because `new` in this translation unit either throws -- in which case, we shouldn't be executing this line -- or succeeds -- in which case, `PFONew` is non-null. http://reviews.llvm.org/D12251 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp created this revision. ismailp added reviewers: zaks.anna, krememek. ismailp added a subscriber: cfe-commits. Name `Out` refers to the parameter. It is moved into the member `Out` in ctor-init. Dereferencing null pointer will crash clang, if user passes '-analyzer-viz-egraph-ubigraph' argument. http://reviews.llvm.org/D12119 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -781,8 +781,8 @@ UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) : Out(std::move(Out)), Filename(Filename), Cntr(0) { - *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; - *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," + *this->Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; + *this->Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," " ('size', '1.5'))\n"; } Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -781,8 +781,8 @@ UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) : Out(std::move(Out)), Filename(Filename), Cntr(0) { - *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; - *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," + *this->Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; + *this->Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," " ('size', '1.5'))\n"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added inline comments. Comment at: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:749 @@ -748,3 +748,3 @@ assert (Src != Dst && "Self-edges are not allowed."); Is Ubigraph generator actively maintained? If I run tests with '-analyzer-viz-egraph-ubigraph', this assertion gets triggered. According to static analyzer documentation, cycles are allowed in ExplodedGraph. I am unsure whether self-cycles are allowed, however. http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp updated this revision to Diff 32745. ismailp added a comment. - Renamed `Out` parameter to `Stm`. - Removed assertion that checks whether an ExplodedNode has an edge to itself. - Added '-analyzer-viz-egraph-ubigraph' to an analyzer invocation in a test. http://reviews.llvm.org/D12119 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/cfg.cpp Index: test/Analysis/cfg.cpp === --- test/Analysis/cfg.cpp +++ test/Analysis/cfg.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -analyzer-viz-egraph-ubigraph -std=c++11 %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s // CHECK-LABEL: void checkWrap(int i) Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -745,9 +745,6 @@ } void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { - - assert (Src != Dst && "Self-edges are not allowed."); - // Lookup the Src. If it is a new node, it's a root. VMap::iterator SrcI= M.find(Src); unsigned SrcID; @@ -778,8 +775,8 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr Stm, StringRef Filename) +: Out(std::move(Stm)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Index: test/Analysis/cfg.cpp === --- test/Analysis/cfg.cpp +++ test/Analysis/cfg.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -analyzer-viz-egraph-ubigraph -std=c++11 %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s // CHECK-LABEL: void checkWrap(int i) Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -745,9 +745,6 @@ } void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { - - assert (Src != Dst && "Self-edges are not allowed."); - // Lookup the Src. If it is a new node, it's a root. VMap::iterator SrcI= M.find(Src); unsigned SrcID; @@ -778,8 +775,8 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr Stm, StringRef Filename) +: Out(std::move(Stm)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D12251: Analyzer: Calculate field offset correctly
ismailp created this revision. ismailp added reviewers: krememek, zaks.anna. ismailp added a subscriber: cfe-commits. `StoreManager::getLValueFieldOrIvar` should return loc as base + field-offset, instead of just base. http://reviews.llvm.org/D12251 Files: lib/StaticAnalyzer/Core/Store.cpp test/Analysis/array-struct-region.cpp Index: test/Analysis/array-struct-region.cpp === --- test/Analysis/array-struct-region.cpp +++ test/Analysis/array-struct-region.cpp @@ -106,6 +106,26 @@ #endif } +struct FieldOffset { + int firstField; + char secondField[63]; + void *thirdField; +}; + +void testFieldOffsets() { + struct FieldOffset FO; + struct FieldOffset *PFONull = 0; +#if __cplusplus + struct FieldOffset *PFONew = new struct FieldOffset; +#endif + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO.thirdField); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFONull->secondField != (void *)&PFONull->thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)&PFONull->secondField == (void *)0); // expected-warning{{TRUE}} +#if __cplusplus + clang_analyzer_eval((void *)&PFONew->secondField != (void *)&PFONew); // expected-warning{{TRUE}} +#endif +} // // C++-only tests Index: lib/StaticAnalyzer/Core/Store.cpp === --- lib/StaticAnalyzer/Core/Store.cpp +++ lib/StaticAnalyzer/Core/Store.cpp @@ -15,6 +15,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" @@ -401,12 +402,21 @@ // These are anormal cases. Flag an undefined value. return UndefinedVal(); - case loc::ConcreteIntKind: -// While these seem funny, this can happen through casts. -// FIXME: What we should return is the field offset. For example, -// add the field offset to the integer value. That way funny things -// like this work properly: &(((struct foo *) 0xa)->f) + case loc::ConcreteIntKind: { +// Don't allow field offset calculations, if base is null. +if (!Base.isZeroConstant()) { + if (const FieldDecl *FD = dyn_cast(D)) { +ASTContext &Ctx = D->getASTContext(); +CharUnits CU = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FD)); +loc::ConcreteInt BasePtr = BaseL.castAs(); +llvm::APSInt Offset(Ctx.getTypeSize(Ctx.VoidPtrTy)); +Offset = CU.getQuantity(); +Offset += BasePtr.getValue(); +return svalBuilder.makeIntLocVal(Offset); + } +} return Base; + } default: llvm_unreachable("Unhandled Base."); Index: test/Analysis/array-struct-region.cpp === --- test/Analysis/array-struct-region.cpp +++ test/Analysis/array-struct-region.cpp @@ -106,6 +106,26 @@ #endif } +struct FieldOffset { + int firstField; + char secondField[63]; + void *thirdField; +}; + +void testFieldOffsets() { + struct FieldOffset FO; + struct FieldOffset *PFONull = 0; +#if __cplusplus + struct FieldOffset *PFONew = new struct FieldOffset; +#endif + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&FO.secondField != (void*)&FO.thirdField); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)&PFONull->secondField != (void *)&PFONull->thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)&PFONull->secondField == (void *)0); // expected-warning{{TRUE}} +#if __cplusplus + clang_analyzer_eval((void *)&PFONew->secondField != (void *)&PFONew); // expected-warning{{TRUE}} +#endif +} // // C++-only tests Index: lib/StaticAnalyzer/Core/Store.cpp === --- lib/StaticAnalyzer/Core/Store.cpp +++ lib/StaticAnalyzer/Core/Store.cpp @@ -15,6 +15,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" @@ -401,12 +402,21 @@ // These are anormal cases. Flag an undefined value. return UndefinedVal(); - case loc::ConcreteIntKind: -// While these seem funny, this can happen through casts. -// FIXME: What we should return is the field offset. For example, -// add the field offset to the integer value. That way funny things -// like this work properly: &(((struct foo *) 0xa)->f) + case loc::ConcreteIntKind: { +// Don't a
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp updated this revision to Diff 32903. ismailp added a comment. - Change parameter name to `OutStream`. http://reviews.llvm.org/D12119 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/cfg.cpp Index: test/Analysis/cfg.cpp === --- test/Analysis/cfg.cpp +++ test/Analysis/cfg.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -analyzer-viz-egraph-ubigraph -std=c++11 %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s // CHECK-LABEL: void checkWrap(int i) Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -745,9 +745,6 @@ } void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { - - assert (Src != Dst && "Self-edges are not allowed."); - // Lookup the Src. If it is a new node, it's a root. VMap::iterator SrcI= M.find(Src); unsigned SrcID; @@ -778,8 +775,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Index: test/Analysis/cfg.cpp === --- test/Analysis/cfg.cpp +++ test/Analysis/cfg.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -analyzer-viz-egraph-ubigraph -std=c++11 %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s // CHECK-LABEL: void checkWrap(int i) Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -745,9 +745,6 @@ } void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { - - assert (Src != Dst && "Self-edges are not allowed."); - // Lookup the Src. If it is a new node, it's a root. VMap::iterator SrcI= M.find(Src); unsigned SrcID; @@ -778,8 +775,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added inline comments. Comment at: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:749 @@ -748,3 @@ - - assert (Src != Dst && "Self-edges are not allowed."); - krememek wrote: > Did you look at the test case that causes this assertion to fail? I think it > would be good to know if this assertion is actually safe to remove. I'm a > bit skeptical that it is safe to remove, and that (per my last review) that > this may be detecting that an invariant is getting violated. If you are not > certain how to investigate that part, please report which test is triggering > the problem and myself or someone else familiar with the engine core can take > a look. Thanks. There wasn't a test that checks Ubigraph generator. After making the patch below, I picked a few existing tests, and added '-analyzer-viz-egraph-ubigraph' to their RUN lines. Then, I ran lit.py, and 'tests/Analysis/cfg.cpp' has crashed. I have minimized the test case to understand the problem. Self-loop happens during implicit destructor of `Aggregate` in the following minimized test case: ``` struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); }; struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; }; void test_lifetime_extended_temporaries() { { Aggregate aggregate{LifetimeExtend(4), LifetimeExtend(4)}; 4; } } ``` The destructor of `a` has a self-loop. My hypothesis is that `a` and `b` have the same `ProgramState`s. `b`'s destructor is visited first, since it's destroyed first. When destructor of `a` gets visited, analyzer calls `ProgramState::Profile` and finds the same state as `b`'s destructor. Therefore, both `a`'s destructor and `b`'s destructor have the same `ExplodedNode`. Do you think this is correct? I have added -analyzer-viz-egraph-ubigraph to a few more C++ tests. I didn't observe any crash. However, I didn't verify that it generates correct ubigraph output. http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D12482: Analyzer: Teach analyzer how to handle TypeTraitExpr
ismailp created this revision. ismailp added reviewers: zaks.anna, dcoughlin, krememek. ismailp added a subscriber: cfe-commits. `TypeTraitExpr`s are not supported by the ExprEngine today. Analyzer creates a sink, and aborts the block. Therefore, certain bugs that involve type traits intrinsics cannot be detected (see PR24710). This patch creates boolean `SVal`s for `TypeTraitExpr`s, which are evaluated by the compiler. Test within the patch is a summary of PR24710. http://reviews.llvm.org/D12482 Files: lib/StaticAnalyzer/Core/Environment.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/SValBuilder.cpp test/Analysis/dtor.cpp Index: test/Analysis/dtor.cpp === --- test/Analysis/dtor.cpp +++ test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -505,3 +505,36 @@ class Foo; // expected-note{{forward declaration}} void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}} } + +namespace TypeTraitExpr { +template +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsSimple = __is_trivial(T) && __is_same(T, U); + copier::do_copy(dest, src, count); +} +struct NonTrivial { + int *p; + NonTrivial() : p(new int[1]) { p[0] = 0; } + NonTrivial(const NonTrivial &other) { +p = new int[1]; +do_copy(p, other.p, 1); + } + NonTrivial &operator=(const NonTrivial &other) { +p = other.p; +return *this; + } + ~NonTrivial() { +delete[] p; // expected-warning {{free released memory}} + } +}; + +void f() { + NonTrivial nt1; + NonTrivial nt2(nt1); + nt1 = nt2; +} +} Index: lib/StaticAnalyzer/Core/SValBuilder.cpp === --- lib/StaticAnalyzer/Core/SValBuilder.cpp +++ lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -259,6 +259,11 @@ case Stmt::CXXBoolLiteralExprClass: return makeBoolVal(cast(E)); + case Stmt::TypeTraitExprClass: { +const TypeTraitExpr *TE = cast(E); +return makeTruthVal(TE->getValue(), TE->getType());; + } + case Stmt::IntegerLiteralClass: return makeIntVal(cast(E)); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp === --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -756,7 +756,6 @@ case Stmt::MSPropertyRefExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::DependentScopeDeclRefExprClass: -case Stmt::TypeTraitExprClass: case Stmt::ArrayTypeTraitExprClass: case Stmt::ExpressionTraitExprClass: case Stmt::UnresolvedLookupExprClass: @@ -775,7 +774,7 @@ Engine.addAbortedBlock(node, currBldrCtx->getBlock()); break; } - + case Stmt::ParenExprClass: llvm_unreachable("ParenExprs already handled."); case Stmt::GenericSelectionExprClass: @@ -902,6 +901,7 @@ case Stmt::ObjCStringLiteralClass: case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: +case Stmt::TypeTraitExprClass: case Stmt::CXXNullPtrLiteralExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; Index: lib/StaticAnalyzer/Core/Environment.cpp === --- lib/StaticAnalyzer/Core/Environment.cpp +++ lib/StaticAnalyzer/Core/Environment.cpp @@ -90,6 +90,7 @@ case Stmt::CXXNullPtrLiteralExprClass: case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: + case Stmt::TypeTraitExprClass: // Known constants; defer to SValBuilder. return svalBuilder.getConstantVal(cast(S)).getValue(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added a comment. Ping! http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp updated this revision to Diff 34082. ismailp added a comment. - Rolled back to the first version of patch, where only parameter `Out` is renamed to `OutStream` - Use a different test that doesn't trigger the self-loop assertion. http://reviews.llvm.org/D12119 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/free.c Index: test/Analysis/free.c === --- test/Analysis/free.c +++ test/Analysis/free.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -analyzer-viz-egraph-ubigraph -verify %s // RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s typedef __typeof(sizeof(int)) size_t; void free(void *); Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," Index: test/Analysis/free.c === --- test/Analysis/free.c +++ test/Analysis/free.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -analyzer-viz-egraph-ubigraph -verify %s // RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s typedef __typeof(sizeof(int)) size_t; void free(void *); Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -778,8 +778,9 @@ << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(std::unique_ptr Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr OutStream, + StringRef Filename) +: Out(std::move(OutStream)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D12119: Analyzer: Fix a crasher in UbigraphViz
ismailp added a comment. Thank you for the feedback! I have added the test in a C file, so we can get the first part of the patch in -- between lines 778-780. I think self-loop is a different problem, and that requires its own patch. I'll see what I can do about self-loop, if someone else isn't working on it. http://reviews.llvm.org/D12119 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D9898: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
ismailp added a comment. Ping! It seems like this patch was forgotten. This fixes PR24730, which is reported recently. http://reviews.llvm.org/D9898 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r251335 - MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
Author: ismailp Date: Mon Oct 26 14:20:24 2015 New Revision: 251335 URL: http://llvm.org/viewvc/llvm-project?rev=251335&view=rev Log: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer Summary: In `MismatchingNewDeleteDetector::analyzeInClassInitializer`, if `Field`'s initializer expression is null, lookup the field in implicit instantiation, and use found field's the initializer. Reviewers: rsmith, rtrieu Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D9898 Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/SemaCXX/delete.cpp Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=251335&r1=251334&r2=251335&view=diff == --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 26 14:20:24 2015 @@ -2500,8 +2500,10 @@ bool MismatchingNewDeleteDetector::hasMa MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); - if (const CXXNewExpr *NE = - getNewExprFromInitListOrExpr(Field->getInClassInitializer())) { + const Expr *InitExpr = Field->getInClassInitializer(); + if (!InitExpr) +return EndOfTU ? NoMismatch : AnalyzeLater; + if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; Modified: cfe/trunk/test/SemaCXX/delete.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete.cpp?rev=251335&r1=251334&r2=251335&view=diff == --- cfe/trunk/test/SemaCXX/delete.cpp (original) +++ cfe/trunk/test/SemaCXX/delete.cpp Mon Oct 26 14:20:24 2015 @@ -120,6 +120,22 @@ void f() { DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} } } + +namespace MissingInitializer { +template +struct Base { + struct S { +const T *p1 = nullptr; +const T *p2 = new T[3]; + }; +}; + +void null_init(Base::S s) { + delete s.p1; + delete s.p2; +} +} + #ifndef WITH_PCH pch_test::X::X() : a(new int[1]) // expected-note{{allocated with 'new[]' here}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D9898: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
This revision was automatically updated to reflect the committed changes. Closed by commit rL251335: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer (authored by ismailp). Changed prior to commit: http://reviews.llvm.org/D9898?vs=26271&id=38449#toc Repository: rL LLVM http://reviews.llvm.org/D9898 Files: cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/SemaCXX/delete.cpp Index: cfe/trunk/lib/Sema/SemaExprCXX.cpp === --- cfe/trunk/lib/Sema/SemaExprCXX.cpp +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp @@ -2500,8 +2500,10 @@ MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); - if (const CXXNewExpr *NE = - getNewExprFromInitListOrExpr(Field->getInClassInitializer())) { + const Expr *InitExpr = Field->getInClassInitializer(); + if (!InitExpr) +return EndOfTU ? NoMismatch : AnalyzeLater; + if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; Index: cfe/trunk/test/SemaCXX/delete.cpp === --- cfe/trunk/test/SemaCXX/delete.cpp +++ cfe/trunk/test/SemaCXX/delete.cpp @@ -120,6 +120,22 @@ DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} } } + +namespace MissingInitializer { +template +struct Base { + struct S { +const T *p1 = nullptr; +const T *p2 = new T[3]; + }; +}; + +void null_init(Base::S s) { + delete s.p1; + delete s.p2; +} +} + #ifndef WITH_PCH pch_test::X::X() : a(new int[1]) // expected-note{{allocated with 'new[]' here}} Index: cfe/trunk/lib/Sema/SemaExprCXX.cpp === --- cfe/trunk/lib/Sema/SemaExprCXX.cpp +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp @@ -2500,8 +2500,10 @@ MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); - if (const CXXNewExpr *NE = - getNewExprFromInitListOrExpr(Field->getInClassInitializer())) { + const Expr *InitExpr = Field->getInClassInitializer(); + if (!InitExpr) +return EndOfTU ? NoMismatch : AnalyzeLater; + if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; Index: cfe/trunk/test/SemaCXX/delete.cpp === --- cfe/trunk/test/SemaCXX/delete.cpp +++ cfe/trunk/test/SemaCXX/delete.cpp @@ -120,6 +120,22 @@ DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} } } + +namespace MissingInitializer { +template +struct Base { + struct S { +const T *p1 = nullptr; +const T *p2 = new T[3]; + }; +}; + +void null_init(Base::S s) { + delete s.p1; + delete s.p2; +} +} + #ifndef WITH_PCH pch_test::X::X() : a(new int[1]) // expected-note{{allocated with 'new[]' here}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r251335 - MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
Hi, this patch addresses a crash-on-valid on 3.7. Could you please merge this to 3.7 branch? Ismail On Mon, Oct 26, 2015 at 8:20 PM, Ismail Pazarbasi via cfe-commits wrote: > Author: ismailp > Date: Mon Oct 26 14:20:24 2015 > New Revision: 251335 > > URL: http://llvm.org/viewvc/llvm-project?rev=251335&view=rev > Log: > MismatchingNewDeleteDetector uses incorrect field, and finds no initializer > > Summary: > In `MismatchingNewDeleteDetector::analyzeInClassInitializer`, if > `Field`'s initializer expression is null, lookup the field in > implicit instantiation, and use found field's the initializer. > > Reviewers: rsmith, rtrieu > > Subscribers: cfe-commits > > Differential Revision: http://reviews.llvm.org/D9898 > > Modified: > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/test/SemaCXX/delete.cpp > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=251335&r1=251334&r2=251335&view=diff > == > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 26 14:20:24 2015 > @@ -2500,8 +2500,10 @@ bool MismatchingNewDeleteDetector::hasMa > MismatchingNewDeleteDetector::MismatchResult > MismatchingNewDeleteDetector::analyzeInClassInitializer() { >assert(Field != nullptr && "This should be called only for members"); > - if (const CXXNewExpr *NE = > - getNewExprFromInitListOrExpr(Field->getInClassInitializer())) { > + const Expr *InitExpr = Field->getInClassInitializer(); > + if (!InitExpr) > +return EndOfTU ? NoMismatch : AnalyzeLater; > + if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { > if (NE->isArray() != IsArrayForm) { >NewExprs.push_back(NE); >return MemberInitMismatches; > > Modified: cfe/trunk/test/SemaCXX/delete.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete.cpp?rev=251335&r1=251334&r2=251335&view=diff > == > --- cfe/trunk/test/SemaCXX/delete.cpp (original) > +++ cfe/trunk/test/SemaCXX/delete.cpp Mon Oct 26 14:20:24 2015 > @@ -120,6 +120,22 @@ void f() { >DELETE(d); // expected-warning {{'delete' applied to a pointer > that was allocated with 'new[]'; did you mean 'delete[]'?}} > } > } > + > +namespace MissingInitializer { > +template > +struct Base { > + struct S { > +const T *p1 = nullptr; > +const T *p2 = new T[3]; > + }; > +}; > + > +void null_init(Base::S s) { > + delete s.p1; > + delete s.p2; > +} > +} > + > #ifndef WITH_PCH > pch_test::X::X() >: a(new int[1]) // expected-note{{allocated with 'new[]' here}} > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [Diffusion] rL251335: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
Thanks! On Fri, Nov 6, 2015 at 12:44 PM, Tom Stellard wrote: > tstellarAMD accepted this commit. > tstellarAMD added a comment. > > r252290 > > > Users: > ismailp (Author) > rsmith (Auditor) > 3.7-release (Auditor) > cfe-commits (Auditor) > tstellarAMD (Auditor) > > http://reviews.llvm.org/rL251335 > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [Diffusion] rL251335: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
ismailp added a subscriber: ismailp. ismailp added a comment. Thanks! Users: ismailp (Author) rsmith (Auditor) 3.7-release (Auditor) cfe-commits (Auditor) tstellarAMD (Auditor) http://reviews.llvm.org/rL251335 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits