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] 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=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
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=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=280837=280838=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=280837=280838=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=280837=280838=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
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
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 + ?
[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] 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
Re: [Diffusion] rL251335: MismatchingNewDeleteDetector uses incorrect field, and finds no initializer
Thanks! On Fri, Nov 6, 2015 at 12:44 PM, Tom Stellardwrote: > 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
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=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 <cfe-commits@lists.llvm.org> wrote: > Author: ismailp > Date: Mon Oct 26 14:20:24 2015 > New Revision: 251335 > > URL: http://llvm.org/viewvc/llvm-project?rev=251335=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=251334=251335=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=251334=251335=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
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=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=251334=251335=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=251334=251335=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] 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 = >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 *) != (void*)); // expected-warning{{TRUE}} + clang_analyzer_eval((void *) != (void*)); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)>secondField != (void *)>thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)>secondField == (void *)0); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)>secondField != (void*)PFOConstant); // expected-warning{{TRUE}} +#if __cplusplus + clang_analyzer_eval((void *)>secondField != (void *)); // 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 = 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 = >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 *) != (void*)); // expected-warning{{TRUE}} + clang_analyzer_eval((void *) != (void*)); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)>secondField != (void *)>thirdField); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)>secondField == (void *)0); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)>secondField != (void*)PFOConstant); // expected-warning{{TRUE}} +#if __cplusplus + clang_analyzer_eval((void *)>secondField != (void *)); // expected-warning{{TRUE}} +#endif +}
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 *)>secondField != (void *)); // 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 `` 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
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=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 ) { +p = new int[1]; +do_copy(p, other.p, 1); + } + NonTrivial =(const NonTrivial ) { +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); @@ -505,3
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 ) { +p = new int[1]; +do_copy(p, other.p, 1); + } + NonTrivial =(const NonTrivial ) { +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 IsSimple =
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
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] 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
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=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=248049=248050=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=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=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. 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] 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
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. 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
[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 bool IsSimple, typename T +struct copier { + static void do_copy(T *dest, const T *src, unsigned count); +}; +template typename T, typename U +void do_copy(T *dest, const U *src, unsigned count) { + const bool IsSimple = __is_trivial(T) __is_same(T, U); + copierIsSimple, T::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(castCXXBoolLiteralExpr(E)); + case Stmt::TypeTraitExprClass: { +const TypeTraitExpr *TE = castTypeTraitExpr(E); +return makeTruthVal(TE-getValue(), TE-getType());; + } + case Stmt::IntegerLiteralClass: return makeIntVal(castIntegerLiteral(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(castExpr(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 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 21 +// 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 21 // 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_ptrraw_ostream Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptrraw_ostream 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 21 +// 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 21 // 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_ptrraw_ostream Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptrraw_ostream 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
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 21 +// 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 21 // 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_ptrraw_ostream Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptrraw_ostream 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 21 +// 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 21 // 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_ptrraw_ostream Out, StringRef Filename) -: Out(std::move(Out)), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptrraw_ostream 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] 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_ptrraw_ostream 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_ptrraw_ostream 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