Re: r338630 - [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext
Il 01/08/2018 22:48, Erich Keane via cfe-commits ha scritto: > Author: erichkeane > Date: Wed Aug 1 13:48:16 2018 > New Revision: 338630 > > URL: http://llvm.org/viewvc/llvm-project?rev=338630&view=rev > Log: > [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into > DeclContext > This commit break the build with gcc version 7.3-win32 20180312 (GCC). I've tracked the cause to the presence of: enum { ObjCMethodFamilyBitWidth = 4 }; between two bitfields declarations. Moving it to begin of class fix the build. This is spotted only because the static_assert, so it is well possible there are other occurrences of the same problem. The following typescript show the issue: abramo@igor:/tmp$ cat bad.cc #include enum { NumDeclContextBits = 13 }; class ObjCMethodDeclBitfields { uint64_t : NumDeclContextBits; enum { ObjCMethodFamilyBitWidth = 4 }; mutable uint64_t Family : ObjCMethodFamilyBitWidth; uint64_t IsInstance : 1; uint64_t IsVariadic : 1; uint64_t IsPropertyAccessor : 1; uint64_t IsDefined : 1; uint64_t IsRedeclaration : 1; mutable uint64_t HasRedeclaration : 1; uint64_t DeclImplementation : 2; uint64_t objcDeclQualifier : 7; uint64_t RelatedResultType : 1; uint64_t SelLocsKind : 2; uint64_t IsOverriding : 1; uint64_t HasSkippedBody : 1; }; static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, "ObjCMethodDeclBitfields is larger than 8 bytes!"); abramo@igor:/tmp$ x86_64-w64-mingw32-g++ -c bad.cc bad.cc:20:1: error: static assertion failed: ObjCMethodDeclBitfields is larger than 8 bytes! static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, ^ 1|abramo@igor:/tmp$ cat good.cc #include enum { NumDeclContextBits = 13 }; class ObjCMethodDeclBitfields { enum { ObjCMethodFamilyBitWidth = 4 }; uint64_t : NumDeclContextBits; mutable uint64_t Family : ObjCMethodFamilyBitWidth; uint64_t IsInstance : 1; uint64_t IsVariadic : 1; uint64_t IsPropertyAccessor : 1; uint64_t IsDefined : 1; uint64_t IsRedeclaration : 1; mutable uint64_t HasRedeclaration : 1; uint64_t DeclImplementation : 2; uint64_t objcDeclQualifier : 7; uint64_t RelatedResultType : 1; uint64_t SelLocsKind : 2; uint64_t IsOverriding : 1; uint64_t HasSkippedBody : 1; }; static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, "ObjCMethodDeclBitfields is larger than 8 bytes!"); abramo@igor:/tmp$ x86_64-w64-mingw32-g++ -c good.cc abramo@igor:/tmp$ -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r282411 - [analyzer] Improve CastToStruct checker so it can also detect widening casts of struct data
Il 26/09/2016 17:17, Daniel Marjamaki via cfe-commits ha scritto: > Author: danielmarjamaki > Date: Mon Sep 26 10:17:18 2016 > New Revision: 282411 > > URL: http://llvm.org/viewvc/llvm-project?rev=282411&view=rev > Log: > [analyzer] Improve CastToStruct checker so it can also detect widening casts > of struct data > > Example: > > struct AB { > int A; > int B; > }; > > struct ABC { > int A; > int B; > int C; > }; > > void f() { > struct AB Data; > struct ABC *P = (struct ABC *)&Data; > } > This commit introduces the regression filed in https://llvm.org/bugs/show_bug.cgi?id=31173 -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Crash in MallocChecker
Please consider to review and apply the attached patch. This is how to reproduce the bug: abramo@tester:~$ cat bug.cpp void f(int a, int b) { new char[a * b]; } abramo@tester:~$ ~/llvm-build/bin/clang -cc1 -analyze -analyzer-checker=cplusplus.NewDeleteLeaks bug.cpp clang: /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:76: T clang::ento::SVal::castAs() const [with T = clang::ento::NonLoc]: Assertion `T::isKind(*this)' failed. #0 0x03689a0f llvm::sys::PrintStackTrace(llvm::raw_ostream&) /home/abramo/llvm/lib/Support/Unix/Signals.inc:402:0 #1 0x03689d6a PrintStackTraceSignalHandler(void*) /home/abramo/llvm/lib/Support/Unix/Signals.inc:466:0 #2 0x03687f30 llvm::sys::RunSignalHandlers() /home/abramo/llvm/lib/Support/Signals.cpp:44:0 #3 0x036893a1 SignalHandler(int) /home/abramo/llvm/lib/Support/Unix/Signals.inc:256:0 #4 0x7f7833b31330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330) #5 0x7f783291dc37 gsignal /build/eglibc-oGUzwX/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0 #6 0x7f7832921028 abort /build/eglibc-oGUzwX/eglibc-2.19/stdlib/abort.c:91:0 #7 0x7f7832916bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.19/assert/assert.c:92:0 #8 0x7f7832916ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2) #9 0x05b1769d clang::ento::NonLoc clang::ento::SVal::castAs() const /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:77:0 #10 0x05bf5a20 (anonymous namespace)::MallocChecker::addExtentSize(clang::ento::CheckerContext&, clang::CXXNewExpr const*, llvm::IntrusiveRefCntPtr) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp:1036:0 #11 0x05bf5601 (anonymous namespace)::MallocChecker::checkPostStmt(clang::CXXNewExpr const*, clang::ento::CheckerContext&) const /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp:991:0 #12 0x05c0aa29 void clang::ento::check::PostStmt::_checkStmt<(anonymous namespace)::MallocChecker>(void*, clang::Stmt const*, clang::ento::CheckerContext&) /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h:105:0 #13 0x05f0d9a8 clang::ento::CheckerFn::operator()(clang::Stmt const*, clang::ento::CheckerContext&) const /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:60:0 #14 0x05f08002 (anonymous namespace)::CheckStmtContext::runChecker(clang::ento::CheckerFn, clang::ento::NodeBuilder&, clang::ento::ExplodedNode*) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:161:0 #15 0x05f0a761 void expandGraphWithCheckers<(anonymous namespace)::CheckStmtContext>((anonymous namespace)::CheckStmtContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:121:0 #16 0x05f080b2 clang::ento::CheckerManager::runCheckersForStmt(bool, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&, clang::Stmt const*, clang::ento::ExprEngine&, bool) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:175:0 #17 0x05f40184 clang::ento::CheckerManager::runCheckersForPostStmt(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&, clang::Stmt const*, clang::ento::ExprEngine&, bool) /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:206:0 #18 0x05f3770a clang::ento::ExprEngine::Visit(clang::Stmt const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:1151:0 #19 0x05f341e4 clang::ento::ExprEngine::ProcessStmt(clang::CFGStmt, clang::ento::ExplodedNode*) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:463:0 #20 0x05f334e4 clang::ento::ExprEngine::processCFGElement(clang::CFGElement, clang::ento::ExplodedNode*, unsigned int, clang::ento::NodeBuilderContext*) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:311:0 #21 0x05f228db clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned int, clang::ento::ExplodedNode*) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:532:0 #22 0x05f217ea clang::ento::CoreEngine::dispatchWorkItem(clang::ento::ExplodedNode*, clang::ProgramPoint, clang::ento::WorkListUnit const&) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:279:0 #23 0x05f213ca clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr) /home/abramo/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:216:0 #24 0x04e7ee6a clang::ento::ExprEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int) /home/abramo/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:109:0 #25 0x04e388be (anonymous namespace)::Analy
Re: Implict casts disappeared from syntactic init list expressions in C++
Ping... Il 29/08/2015 10:01, Abramo Bagnara ha scritto: > Il 28/08/2015 23:27, Richard Smith ha scritto: >> On Tue, Aug 25, 2015 at 10:27 AM, Abramo Bagnara >> mailto:abramo.bagn...@bugseng.com>> wrote: >> >> Comparing the result of InitListExpr::getSyntacticForm between r224986 >> and r245836 I've discovered that integer to char implicit cast for >> integer literal 3 is no longer added to AST for C++ (while it is present >> in C). >> >> This is the source used to test: >> >> char v[10] = { 3 }; >> >> Taken in account that: >> >> - implicit cast (and other conversions, constructor calls, etc.) are >> very important also for who need to visit the syntactic form (obvious in >> *both* C and C++) >> >> - to generate that for the syntactic form permit to increase the >> efficiency and the sharing when using designated range extensions (as >> the conversion chain don't need to be replicated for each entry) >> >> I think it is a regression. Am I missing something? >> >> >> Why do you expect this semantic information to appear in the syntactic >> form of the initializer? > > Compare: > > int x = 2.0; > > with > > struct s { > int x; > } v = { .x = 2.0 }; > > For first declaration I have non-syntactic nodes (namely > ImplicitCastExpr) along with syntactic nodes, while for the second I > don't have that (for C++). This is an obstacle to write semi-syntactic > checkers that aims to find e.g. implicit cast from double to int in its > syntactic context. > Note that although we might visit the semantic form, we'll lose the > designators (not present in semantic form). > > To resume, the reason why I would expect that are: > > 1) this is how it always has worked for C (and fortunately still works > this way) > > > 2) this is how it always has worked (although partially, there was some > bugs) for C++. In past we have had patches to fix the areas where this > invariant was not respected (see commit 3146766 > http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20111212/050339.html > as an example). > > This behavior has changed rather recently (if you think it is useful I > can find the commit that has removed the implicit casts from syntactic > form in C++) > > Before such commit(s) the only bug I was aware where AST was missing > conversion chain was the following: > > struct R2 { > R2(int) { > } > }; > R2 v2[] = { 1.0 }; > > > 3) this way it would be congruent with other areas of AST where we have > non-syntactic nodes along with syntactic ones > > > 4) it would permit to share more nodes in semantic form (and avoid to > rebuild many times the same conversion chain). > > Looking at following typescript you can observe that ImplicitCastExpr is > shared only for C, but not for C++. I've initialized only two entries, > but it might be 1000 or 1000. > > $ cat p.c > int x[100] = { [0 ... 1] = 3.0 }; > $ clang-3.8 -cc1 -ast-dump -x c p.c > TranslationUnitDecl 0x272de40 <> > |-TypedefDecl 0x272e338 <> implicit > __int128_t '__int128' > |-TypedefDecl 0x272e398 <> implicit > __uint128_t 'unsigned __int128' > |-TypedefDecl 0x272e648 <> implicit > __builtin_va_list 'struct __va_list_tag [1]' > `-VarDecl 0x272e718 col:5 x 'int [100]' cinit > `-InitListExpr 0x272e8b0 'int [100]' > |-array filler > | `-ImplicitValueInitExpr 0x272e918 <> 'int' > |-ImplicitCastExpr 0x272e900 'int' > | `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 > `-ImplicitCastExpr 0x272e900 'int' > `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 > $ clang-3.8 -cc1 -ast-dump -x c++ p.c > TranslationUnitDecl 0x3300e60 <> > |-TypedefDecl 0x3301398 <> implicit > __int128_t '__int128' > |-TypedefDecl 0x33013f8 <> implicit > __uint128_t 'unsigned __int128' > |-TypedefDecl 0x3301718 <> implicit > __builtin_va_list 'struct __va_list_tag [1]' > `-VarDecl 0x33017e8 col:5 x 'int [100]' cinit > `-InitListExpr 0x3301980 'int [100]' > |-array filler > | `-ImplicitValueInitExpr 0x3301a00 <> 'int' > |-ImplicitCastExpr 0x33019d0 'int' > | `-FloatingLiteral 0x33018c8 'double' 3.00e+00 > `-ImplicitCastExpr 0x33019e8 'int' > `-FloatingLiteral 0x33018c8 'double' 3.00e+00 > > > 5) if we would visit semantic form in a checker searching for implicit > cast from float to int in the C source above we'll find *two* of them, > while syntactically we have only one. This means that we should be > forced do some dirty tricks to avoid double reporting. > -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Ping^2... Il 29/08/2015 10:01, Abramo Bagnara ha scritto: > Il 28/08/2015 23:27, Richard Smith ha scritto: >> On Tue, Aug 25, 2015 at 10:27 AM, Abramo Bagnara >> mailto:abramo.bagn...@bugseng.com>> wrote: >> >> Comparing the result of InitListExpr::getSyntacticForm between r224986 >> and r245836 I've discovered that integer to char implicit cast for >> integer literal 3 is no longer added to AST for C++ (while it is present >> in C). >> >> This is the source used to test: >> >> char v[10] = { 3 }; >> >> Taken in account that: >> >> - implicit cast (and other conversions, constructor calls, etc.) are >> very important also for who need to visit the syntactic form (obvious in >> *both* C and C++) >> >> - to generate that for the syntactic form permit to increase the >> efficiency and the sharing when using designated range extensions (as >> the conversion chain don't need to be replicated for each entry) >> >> I think it is a regression. Am I missing something? >> >> >> Why do you expect this semantic information to appear in the syntactic >> form of the initializer? > > Compare: > > int x = 2.0; > > with > > struct s { > int x; > } v = { .x = 2.0 }; > > For first declaration I have non-syntactic nodes (namely > ImplicitCastExpr) along with syntactic nodes, while for the second I > don't have that (for C++). This is an obstacle to write semi-syntactic > checkers that aims to find e.g. implicit cast from double to int in its > syntactic context. > Note that although we might visit the semantic form, we'll lose the > designators (not present in semantic form). > > To resume, the reason why I would expect that are: > > 1) this is how it always has worked for C (and fortunately still works > this way) > > > 2) this is how it always has worked (although partially, there was some > bugs) for C++. In past we have had patches to fix the areas where this > invariant was not respected (see commit 3146766 > http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20111212/050339.html > as an example). > > This behavior has changed rather recently (if you think it is useful I > can find the commit that has removed the implicit casts from syntactic > form in C++) > > Before such commit(s) the only bug I was aware where AST was missing > conversion chain was the following: > > struct R2 { > R2(int) { > } > }; > R2 v2[] = { 1.0 }; > > > 3) this way it would be congruent with other areas of AST where we have > non-syntactic nodes along with syntactic ones > > > 4) it would permit to share more nodes in semantic form (and avoid to > rebuild many times the same conversion chain). > > Looking at following typescript you can observe that ImplicitCastExpr is > shared only for C, but not for C++. I've initialized only two entries, > but it might be 1000 or 1000. > > $ cat p.c > int x[100] = { [0 ... 1] = 3.0 }; > $ clang-3.8 -cc1 -ast-dump -x c p.c > TranslationUnitDecl 0x272de40 <> > |-TypedefDecl 0x272e338 <> implicit > __int128_t '__int128' > |-TypedefDecl 0x272e398 <> implicit > __uint128_t 'unsigned __int128' > |-TypedefDecl 0x272e648 <> implicit > __builtin_va_list 'struct __va_list_tag [1]' > `-VarDecl 0x272e718 col:5 x 'int [100]' cinit > `-InitListExpr 0x272e8b0 'int [100]' > |-array filler > | `-ImplicitValueInitExpr 0x272e918 <> 'int' > |-ImplicitCastExpr 0x272e900 'int' > | `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 > `-ImplicitCastExpr 0x272e900 'int' > `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 > $ clang-3.8 -cc1 -ast-dump -x c++ p.c > TranslationUnitDecl 0x3300e60 <> > |-TypedefDecl 0x3301398 <> implicit > __int128_t '__int128' > |-TypedefDecl 0x33013f8 <> implicit > __uint128_t 'unsigned __int128' > |-TypedefDecl 0x3301718 <> implicit > __builtin_va_list 'struct __va_list_tag [1]' > `-VarDecl 0x33017e8 col:5 x 'int [100]' cinit > `-InitListExpr 0x3301980 'int [100]' > |-array filler > | `-ImplicitValueInitExpr 0x3301a00 <> 'int' > |-ImplicitCastExpr 0x33019d0 'int' > | `-FloatingLiteral 0x33018c8 'double' 3.00e+00 > `-ImplicitCastExpr 0x33019e8 'int' > `-FloatingLiteral 0x33018c8 'double' 3.00e+00 > > > 5) if we would visit semantic form in a checker searching for implicit > cast from float to int in the C source above we'll find *two* of them, > while syntactically we have only one. This means that we should be > forced do some dirty tricks to avoid double reporting. > -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Implict casts disappeared from syntactic init list expressions in C++
Comparing the result of InitListExpr::getSyntacticForm between r224986 and r245836 I've discovered that integer to char implicit cast for integer literal 3 is no longer added to AST for C++ (while it is present in C). This is the source used to test: char v[10] = { 3 }; Taken in account that: - implicit cast (and other conversions, constructor calls, etc.) are very important also for who need to visit the syntactic form (obvious in *both* C and C++) - to generate that for the syntactic form permit to increase the efficiency and the sharing when using designated range extensions (as the conversion chain don't need to be replicated for each entry) I think it is a regression. Am I missing something? -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Ping. Il 25/08/2015 19:27, Abramo Bagnara ha scritto: > Comparing the result of InitListExpr::getSyntacticForm between r224986 > and r245836 I've discovered that integer to char implicit cast for > integer literal 3 is no longer added to AST for C++ (while it is present > in C). > > This is the source used to test: > > char v[10] = { 3 }; > > Taken in account that: > > - implicit cast (and other conversions, constructor calls, etc.) are > very important also for who need to visit the syntactic form (obvious in > *both* C and C++) > > - to generate that for the syntactic form permit to increase the > efficiency and the sharing when using designated range extensions (as > the conversion chain don't need to be replicated for each entry) > > I think it is a regression. Am I missing something? > -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Il 28/08/2015 23:27, Richard Smith ha scritto: > On Tue, Aug 25, 2015 at 10:27 AM, Abramo Bagnara > mailto:abramo.bagn...@bugseng.com>> wrote: > > Comparing the result of InitListExpr::getSyntacticForm between r224986 > and r245836 I've discovered that integer to char implicit cast for > integer literal 3 is no longer added to AST for C++ (while it is present > in C). > > This is the source used to test: > > char v[10] = { 3 }; > > Taken in account that: > > - implicit cast (and other conversions, constructor calls, etc.) are > very important also for who need to visit the syntactic form (obvious in > *both* C and C++) > > - to generate that for the syntactic form permit to increase the > efficiency and the sharing when using designated range extensions (as > the conversion chain don't need to be replicated for each entry) > > I think it is a regression. Am I missing something? > > > Why do you expect this semantic information to appear in the syntactic > form of the initializer? Compare: int x = 2.0; with struct s { int x; } v = { .x = 2.0 }; For first declaration I have non-syntactic nodes (namely ImplicitCastExpr) along with syntactic nodes, while for the second I don't have that (for C++). This is an obstacle to write semi-syntactic checkers that aims to find e.g. implicit cast from double to int in its syntactic context. Note that although we might visit the semantic form, we'll lose the designators (not present in semantic form). To resume, the reason why I would expect that are: 1) this is how it always has worked for C (and fortunately still works this way) 2) this is how it always has worked (although partially, there was some bugs) for C++. In past we have had patches to fix the areas where this invariant was not respected (see commit 3146766 http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20111212/050339.html as an example). This behavior has changed rather recently (if you think it is useful I can find the commit that has removed the implicit casts from syntactic form in C++) Before such commit(s) the only bug I was aware where AST was missing conversion chain was the following: struct R2 { R2(int) { } }; R2 v2[] = { 1.0 }; 3) this way it would be congruent with other areas of AST where we have non-syntactic nodes along with syntactic ones 4) it would permit to share more nodes in semantic form (and avoid to rebuild many times the same conversion chain). Looking at following typescript you can observe that ImplicitCastExpr is shared only for C, but not for C++. I've initialized only two entries, but it might be 1000 or 1000. $ cat p.c int x[100] = { [0 ... 1] = 3.0 }; $ clang-3.8 -cc1 -ast-dump -x c p.c TranslationUnitDecl 0x272de40 <> |-TypedefDecl 0x272e338 <> implicit __int128_t '__int128' |-TypedefDecl 0x272e398 <> implicit __uint128_t 'unsigned __int128' |-TypedefDecl 0x272e648 <> implicit __builtin_va_list 'struct __va_list_tag [1]' `-VarDecl 0x272e718 col:5 x 'int [100]' cinit `-InitListExpr 0x272e8b0 'int [100]' |-array filler | `-ImplicitValueInitExpr 0x272e918 <> 'int' |-ImplicitCastExpr 0x272e900 'int' | `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 `-ImplicitCastExpr 0x272e900 'int' `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 $ clang-3.8 -cc1 -ast-dump -x c++ p.c TranslationUnitDecl 0x3300e60 <> |-TypedefDecl 0x3301398 <> implicit __int128_t '__int128' |-TypedefDecl 0x33013f8 <> implicit __uint128_t 'unsigned __int128' |-TypedefDecl 0x3301718 <> implicit __builtin_va_list 'struct __va_list_tag [1]' `-VarDecl 0x33017e8 col:5 x 'int [100]' cinit `-InitListExpr 0x3301980 'int [100]' |-array filler | `-ImplicitValueInitExpr 0x3301a00 <> 'int' |-ImplicitCastExpr 0x33019d0 'int' | `-FloatingLiteral 0x33018c8 'double' 3.00e+00 `-ImplicitCastExpr 0x33019e8 'int' `-FloatingLiteral 0x33018c8 'double' 3.00e+00 5) if we would visit semantic form in a checker searching for implicit cast from float to int in the C source above we'll find *two* of them, while syntactically we have only one. This means that we should be forced do some dirty tricks to avoid double reporting. -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Ping^2 Il 12/09/2015 09:40, Abramo Bagnara ha scritto: > Ping... > > Il 29/08/2015 10:01, Abramo Bagnara ha scritto: >> Il 28/08/2015 23:27, Richard Smith ha scritto: >>> On Tue, Aug 25, 2015 at 10:27 AM, Abramo Bagnara >>> mailto:abramo.bagn...@bugseng.com>> wrote: >>> >>> Comparing the result of InitListExpr::getSyntacticForm between r224986 >>> and r245836 I've discovered that integer to char implicit cast for >>> integer literal 3 is no longer added to AST for C++ (while it is present >>> in C). >>> >>> This is the source used to test: >>> >>> char v[10] = { 3 }; >>> >>> Taken in account that: >>> >>> - implicit cast (and other conversions, constructor calls, etc.) are >>> very important also for who need to visit the syntactic form (obvious in >>> *both* C and C++) >>> >>> - to generate that for the syntactic form permit to increase the >>> efficiency and the sharing when using designated range extensions (as >>> the conversion chain don't need to be replicated for each entry) >>> >>> I think it is a regression. Am I missing something? >>> >>> >>> Why do you expect this semantic information to appear in the syntactic >>> form of the initializer? >> >> Compare: >> >> int x = 2.0; >> >> with >> >> struct s { >> int x; >> } v = { .x = 2.0 }; >> >> For first declaration I have non-syntactic nodes (namely >> ImplicitCastExpr) along with syntactic nodes, while for the second I >> don't have that (for C++). This is an obstacle to write semi-syntactic >> checkers that aims to find e.g. implicit cast from double to int in its >> syntactic context. >> Note that although we might visit the semantic form, we'll lose the >> designators (not present in semantic form). >> >> To resume, the reason why I would expect that are: >> >> 1) this is how it always has worked for C (and fortunately still works >> this way) >> >> >> 2) this is how it always has worked (although partially, there was some >> bugs) for C++. In past we have had patches to fix the areas where this >> invariant was not respected (see commit 3146766 >> http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20111212/050339.html >> as an example). >> >> This behavior has changed rather recently (if you think it is useful I >> can find the commit that has removed the implicit casts from syntactic >> form in C++) >> >> Before such commit(s) the only bug I was aware where AST was missing >> conversion chain was the following: >> >> struct R2 { >> R2(int) { >> } >> }; >> R2 v2[] = { 1.0 }; >> >> >> 3) this way it would be congruent with other areas of AST where we have >> non-syntactic nodes along with syntactic ones >> >> >> 4) it would permit to share more nodes in semantic form (and avoid to >> rebuild many times the same conversion chain). >> >> Looking at following typescript you can observe that ImplicitCastExpr is >> shared only for C, but not for C++. I've initialized only two entries, >> but it might be 1000 or 1000. >> >> $ cat p.c >> int x[100] = { [0 ... 1] = 3.0 }; >> $ clang-3.8 -cc1 -ast-dump -x c p.c >> TranslationUnitDecl 0x272de40 <> >> |-TypedefDecl 0x272e338 <> implicit >> __int128_t '__int128' >> |-TypedefDecl 0x272e398 <> implicit >> __uint128_t 'unsigned __int128' >> |-TypedefDecl 0x272e648 <> implicit >> __builtin_va_list 'struct __va_list_tag [1]' >> `-VarDecl 0x272e718 col:5 x 'int [100]' cinit >> `-InitListExpr 0x272e8b0 'int [100]' >> |-array filler >> | `-ImplicitValueInitExpr 0x272e918 <> 'int' >> |-ImplicitCastExpr 0x272e900 'int' >> | `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 >> `-ImplicitCastExpr 0x272e900 'int' >> `-FloatingLiteral 0x272e7f8 'double' 3.00e+00 >> $ clang-3.8 -cc1 -ast-dump -x c++ p.c >> TranslationUnitDecl 0x3300e60 <> >> |-TypedefDecl 0x3301398 <> implicit >> __int128_t '__int128' >> |-TypedefDecl 0x33013f8 <> implicit >> __uint128_t 'unsigned __int128' >> |-TypedefDecl 0x3301718 <> implicit >> __builtin_va_list 'struct __va_list_tag [1]' >> `-VarDecl 0x33017e8 col:5 x 'int [100]' cinit >> `-InitListExpr 0x3301980 'int [100]' >> |-array filler >> | `-ImplicitValueInitExpr 0x3301a00 <> 'int' >> |-ImplicitCastExpr 0x33019d0 'int' >> | `-FloatingLiteral 0x33018c8 'double' 3.00e+00 >> `-ImplicitCastExpr 0x33019e8 'int' >> `-FloatingLiteral 0x33018c8 'double' 3.00e+00 >> >> >> 5) if we would visit semantic form in a checker searching for implicit >> cast from float to int in the C source above we'll find *two* of them, >> while syntactically we have only one. This means that we should be >> forced do some dirty tricks to avoid double reporting. >> > > -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Il 08/10/2015 23:36, Richard Smith ha scritto: > There are some other open problems in this area: > > - RecursiveASTVisitor on nested InitListExprs is currently worst-case > exponential time because it walks the syntactic and semantic forms > separately > - Tools such as "find all references to this function" need the semantic > form of every initializer, whether or not that initializer is actually > used for the initialization (it might be overridden through the use of a > designator) > - ... > > Having thought about this for a while, I think the right answer is this: > > The only difference between the syntactic and semantic forms of an > InitListExpr should be designated initializers and brace elision. In all > other respects, the syntactic and semantic forms should be identical -- > in particular, both should contain the results of performing the > relevant initialization sequences on the list elements, and we should > extend the syntactic form to include the implicit initializations for > trailing elements. I suppose that you are proposing to include implicit initializations for trailing elements to have in syntactic form all the references. Note however that what you suggest is not enough when extending C++ with designated initializers (like gcc and clang do, at least partially). This is an example: struct f1 { f1(); }; struct f2 { f2(); }; struct s { f1 x; f2 y; }; s v = { .x = f1() }; You can easily imagine a similar example where the same effect is obtained with an array (three elements, first and third are explicitly initialized). IMHO it is better to avoid to add implicit fields/array elements initialization in syntactic form and let tools that need to collect implicit constructor reference to find a different way, e.g. scanning semantic form for ImplicitValueInitExpr children of InitListExpr (unfortunately currently not present (by mistake I guess, but I'd like to hear your opinion) as you can observe from -ast-dump output of previous example). > With that in hand, we should make RecursiveASTVisitor visit /only/ the > syntactic form. The semantic ("simplified") form should only be used in > places where we want to know the semantic effect of the initialization > (after applying the designated initialization overriding rules and > inserting the elided braces), and is always derivable in a fairly > straightforward fashion from the syntactic form. > > I think that's largely what you were suggesting below. Do you agree? Apart the doubt about the detail above, your design matches perfectly my suggestions. -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: Implict casts disappeared from syntactic init list expressions in C++
Ping (I still need your feedback so that I can open a properly documented issue on bugzilla). Il 09/10/2015 09:58, Abramo Bagnara ha scritto: > Il 08/10/2015 23:36, Richard Smith ha scritto: >> There are some other open problems in this area: >> >> - RecursiveASTVisitor on nested InitListExprs is currently worst-case >> exponential time because it walks the syntactic and semantic forms >> separately >> - Tools such as "find all references to this function" need the semantic >> form of every initializer, whether or not that initializer is actually >> used for the initialization (it might be overridden through the use of a >> designator) >> - ... >> >> Having thought about this for a while, I think the right answer is this: >> >> The only difference between the syntactic and semantic forms of an >> InitListExpr should be designated initializers and brace elision. In all >> other respects, the syntactic and semantic forms should be identical -- >> in particular, both should contain the results of performing the >> relevant initialization sequences on the list elements, and we should >> extend the syntactic form to include the implicit initializations for >> trailing elements. > > I suppose that you are proposing to include implicit initializations for > trailing elements to have in syntactic form all the references. > > Note however that what you suggest is not enough when extending C++ with > designated initializers (like gcc and clang do, at least partially). > > This is an example: > > struct f1 { > f1(); > }; > struct f2 { > f2(); > }; > > struct s { > f1 x; > f2 y; > }; > > s v = { .x = f1() }; > > You can easily imagine a similar example where the same effect is > obtained with an array (three elements, first and third are explicitly > initialized). > > IMHO it is better to avoid to add implicit fields/array elements > initialization in syntactic form and let tools that need to collect > implicit constructor reference to find a different way, e.g. scanning > semantic form for ImplicitValueInitExpr children of InitListExpr > (unfortunately currently not present (by mistake I guess, but I'd like > to hear your opinion) as you can observe from -ast-dump output of > previous example). > >> With that in hand, we should make RecursiveASTVisitor visit /only/ the >> syntactic form. The semantic ("simplified") form should only be used in >> places where we want to know the semantic effect of the initialization >> (after applying the designated initialization overriding rules and >> inserting the elided braces), and is always derivable in a fairly >> straightforward fashion from the syntactic form. >> >> I think that's largely what you were suggesting below. Do you agree? > > Apart the doubt about the detail above, your design matches perfectly my > suggestions. > > -- Abramo Bagnara BUGSENG srl - http://bugseng.com mailto:abramo.bagn...@bugseng.com ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits