diff --git a/External/CheckerGccPlugins/CMakeLists.txt b/External/CheckerGccPlugins/CMakeLists.txt index e7ac6944eaa894c6ab4620be3438830f068cc0b9..49afe0d20ad2e0d5c5c9ac84012707ed6dec54fd 100644 --- a/External/CheckerGccPlugins/CMakeLists.txt +++ b/External/CheckerGccPlugins/CMakeLists.txt @@ -1,4 +1,4 @@ -# $Id: CMakeLists.txt 756969 2016-06-22 14:03:26Z krasznaa $ +# $Id: CMakeLists.txt 781116 2016-10-28 23:16:43Z ssnyder $ # The name of the package: atlas_subdir( CheckerGccPlugins ) @@ -57,7 +57,7 @@ endfunction( CheckerGccPlugins_test ) CheckerGccPlugins_test( gaudi_inheritance ) CheckerGccPlugins_test( divcheck ) CheckerGccPlugins_test( naming ) -CheckerGccPlugins_test( ists1 ) +CheckerGccPlugins_test( check_ts1 ) CheckerGccPlugins_test( thread1 ) CheckerGccPlugins_test( thread2 ) CheckerGccPlugins_test( thread3 ) @@ -65,6 +65,7 @@ CheckerGccPlugins_test( thread4 ) CheckerGccPlugins_test( thread5 ) CheckerGccPlugins_test( thread6 ) CheckerGccPlugins_test( thread7 ) +CheckerGccPlugins_test( thread8 ) #CheckerGccPlugins_test( usingns1 ) #CheckerGccPlugins_test( usingns2 ) #CheckerGccPlugins_test( usingns3 ) diff --git a/External/CheckerGccPlugins/THREAD_CHECKS b/External/CheckerGccPlugins/THREAD_CHECKS new file mode 100644 index 0000000000000000000000000000000000000000..9303f101248581702f8bbd4937fdc14ae5ee8daa --- /dev/null +++ b/External/CheckerGccPlugins/THREAD_CHECKS @@ -0,0 +1,140 @@ +Enabling thread checks. One of the following: + + - Function or type directly has a gnu::check_thread_safety attribute. + - Containing context for a function of type + has a gnu::check_thread_safety attribute. + - File contains `#pragma ATLAS check_thread_safety'. + - The package contains a file ATLAS_CHECK_THREAD_SAFETY. + + +========================================================================= +check_direct_static_use (thread1_test) + Warns about use of a non-const static value. + +int f1(int xx) +{ + static int x; + x = xx; + return x; +} + + gets two warnings. + + Can suppress by: + - Declaring value as thread_local. + static thread_local int x; + + - Adding a thread_safe attribute: + static int x [[gnu::thread_safe]]; + + - Adding not_thread_safe or not_reentrant to the function: + int f5 [[gnu::not_thread_safe]] (int xx) + int f6 [[gnu::not_reentrant]] (int xx) + + +========================================================================= +check_assign_address_of_static (thread2_test) + +Check for binding a non-const pointer or reference to a static. + +For example: + +static int y1; +int* f1() +{ + return &y1; +} + + + Can suppress by: + - Declaring value as thread_local. + static thread_local int y1; + + - Adding a thread_safe attribute: + static int x [[gnu::thread_safe]]; + + - Adding not_thread_safe or not_reentrant to the function: + int f5 [[gnu::not_thread_safe]] (int xx) + int f6 [[gnu::not_reentrant]] (int xx) + + +========================================================================= +check_pass_static_by_call (thread3_test) + +Check for passing a static to a non-const pointer or reference +function argument. + +Example: + +static int y1; +void foo1(int, int*); +void f1() +{ + foo1(3, &y1); +} + + + Can suppress by: + - Declaring value as thread_local. + static thread_local int y1; + + - Adding a thread_safe attribute: + static int x [[gnu::thread_safe]]; + + - Adding not_thread_safe or not_reentrant to the function: + int f5 [[gnu::not_thread_safe]] (int xx) + int f6 [[gnu::not_reentrant]] (int xx) + + +========================================================================= +check_discarded_const (thread4_test) + + +Check for discarding const from a pointer/reference. + +Example: + +int* f1(const int* y) +{ + return const_cast<int*>(y); +} + + + Can suppress by: + + - Adding a thread_safe attribute to the LHS of an assignment + that discards const: + const int* y; + int* yy [[gnu::thread_safe]] = (int*)y; + + - Adding a not_thread_safe attribute to the function. + + - Adding a not_const_thread_safe attribute to the function, when + it discards const from something that is not an argument. + + - Adding an argument_not_const_thread_safe attribute to the function, when + it discards const from an argument. + + +========================================================================= +check_discarded_const_in_funcall (thread5_test) + + +Check for discarding const from a pointer/reference in a function call. + +Example: + +const int* xx(); +void f1(int* y); +void f2(const int* y) +{ + f1(const_cast<int*>(y)); +} + + + Can suppress by: + + - Adding a not_thread_safe attribute to the function. + + - Adding a not_const_thread_safe attribute to the function, when + it discards const from something that is not an argument. diff --git a/External/CheckerGccPlugins/cmt/requirements b/External/CheckerGccPlugins/cmt/requirements index 34b62576f888ed898a8695ab2672a3bb61350411..4bc44b4a50d2c044518a26cf8c90cd9898f560e5 100644 --- a/External/CheckerGccPlugins/cmt/requirements +++ b/External/CheckerGccPlugins/cmt/requirements @@ -126,7 +126,7 @@ apply_pattern checker_test name=divcheck #apply_pattern checker_test name=usingns6 #apply_pattern checker_test name=usingns7 apply_pattern checker_test name=naming -apply_pattern checker_test name=ists1 +apply_pattern checker_test name=check_ts1 apply_pattern checker_test name=thread1 apply_pattern checker_test name=thread2 apply_pattern checker_test name=thread3 @@ -134,4 +134,5 @@ apply_pattern checker_test name=thread4 apply_pattern checker_test name=thread5 apply_pattern checker_test name=thread6 apply_pattern checker_test name=thread7 +apply_pattern checker_test name=thread8 diff --git a/External/CheckerGccPlugins/share/check_ts1_test.ref b/External/CheckerGccPlugins/share/check_ts1_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..150be419bb0a9491426aeb653f9f04384b2ea5a6 --- /dev/null +++ b/External/CheckerGccPlugins/share/check_ts1_test.ref @@ -0,0 +1,73 @@ +In file included from /home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:1:0: +/home/sss/atlas/rootaccess/../test/check_ts1_test1.h: In function 'void i1()': +/home/sss/atlas/rootaccess/../test/check_ts1_test1.h:3:6: warning: 'void i1()' is marked thread-safe. + void i1 [[gnu::check_thread_safety_debug]] () {} + ^~ +In file included from /home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:2:0: +/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1a.h: In function 'void p1a()': +/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1a.h:1:6: warning: 'void p1a()' is marked thread-safe. + void p1a [[gnu::check_thread_safety_debug]] () {} + ^~~ +In file included from /home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:3:0: +/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1b.h: In function 'void p1b()': +/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1b.h:1:6: warning: 'void p1b()' is marked thread-safe. + void p1b [[gnu::check_thread_safety_debug]] () {} + ^~~ +In file included from /home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:4:0: +/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2a.h: In function 'void p2a()': +/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2a.h:1:6: warning: 'void p2a()' is not marked thread-safe. + void p2a [[gnu::check_thread_safety_debug]] () {} + ^~~ +In file included from /home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:5:0: +/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2b.h: In function 'void p2b()': +/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2b.h:1:6: warning: 'void p2b()' is not marked thread-safe. + void p2b [[gnu::check_thread_safety_debug]] () {} + ^~~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In function 'void f1()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:7:6: warning: 'void f1()' is not marked thread-safe. + void f1 [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In function 'void f2()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:8:6: warning: 'void f2()' is marked thread-safe. + void f2 [[gnu::check_thread_safety_debug]] [[gnu::check_thread_safety]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: At global scope: +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:13:8: warning: 'void C1::g1()' is not marked thread-safe. + void g1 [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:14:8: warning: 'void C1::g2()' is not marked thread-safe. + void g2 [[gnu::check_thread_safety_debug]] (); + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:16:8: warning: 'void C1::g4()' is marked thread-safe. + void g4 [[gnu::check_thread_safety]] [[gnu::check_thread_safety_debug]] (); + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:17:8: warning: 'void C1::g5()' is not marked thread-safe. + void g5 [[gnu::not_thread_safe]] [[gnu::check_thread_safety_debug]] (); + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In member function 'void C1::g2()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:21:6: warning: 'void C1::g2()' is not marked thread-safe. + void C1::g2() {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In member function 'void C1::g3()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:22:6: warning: 'void C1::g3()' is not marked thread-safe. + void C1::g3 [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In member function 'void C1::g4()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:23:6: warning: 'void C1::g4()' is marked thread-safe. + void C1::g4() {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: At global scope: +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:28:8: warning: 'void C2::h1()' is marked thread-safe. + void h1 [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:35:8: warning: 'void C2::h4()' is not marked thread-safe. + void h4 [[gnu::not_thread_safe]] [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In member function 'void C2::h2()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:38:6: warning: 'void C2::h2()' is marked thread-safe. + void C2::h2 [[gnu::check_thread_safety_debug]] () {} + ^~ +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx: In member function 'void C2::C3::h3()': +/home/sss/atlas/rootaccess/../test/check_ts1_test.cxx:39:6: warning: 'void C2::C3::h3()' is marked thread-safe. + void C2::C3::h3 [[gnu::check_thread_safety_debug]] () {} + ^~ diff --git a/External/CheckerGccPlugins/share/ists1_test.ref b/External/CheckerGccPlugins/share/ists1_test.ref deleted file mode 100644 index 5218146a99e48f5551ecd37ffa968ef28f076aac..0000000000000000000000000000000000000000 --- a/External/CheckerGccPlugins/share/ists1_test.ref +++ /dev/null @@ -1,67 +0,0 @@ -In file included from /home/sss/atlas/rootaccess/../test/ists1_test.cxx:1:0: -/home/sss/atlas/rootaccess/../test/ists1_test1.h: In function 'void i1()': -/home/sss/atlas/rootaccess/../test/ists1_test1.h:3:6: warning: 'void i1()' is marked thread-safe. - void i1 [[gnu::thread_safe_debug]] () {} - ^ -In file included from /home/sss/atlas/rootaccess/../test/ists1_test.cxx:2:0: -/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1a.h: In function 'void p1a()': -/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1a.h:1:6: warning: 'void p1a()' is marked thread-safe. - void p1a [[gnu::thread_safe_debug]] () {} - ^ -In file included from /home/sss/atlas/rootaccess/../test/ists1_test.cxx:3:0: -/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1b.h: In function 'void p1b()': -/home/sss/atlas/rootaccess/../test/Control/p1/p1/p1b.h:1:6: warning: 'void p1b()' is marked thread-safe. - void p1b [[gnu::thread_safe_debug]] () {} - ^ -In file included from /home/sss/atlas/rootaccess/../test/ists1_test.cxx:4:0: -/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2a.h: In function 'void p2a()': -/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2a.h:1:6: warning: 'void p2a()' is not marked thread-safe. - void p2a [[gnu::thread_safe_debug]] () {} - ^ -In file included from /home/sss/atlas/rootaccess/../test/ists1_test.cxx:5:0: -/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2b.h: In function 'void p2b()': -/home/sss/atlas/rootaccess/../test/Control/p2/p2/p2b.h:1:6: warning: 'void p2b()' is not marked thread-safe. - void p2b [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In function 'void f1()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:7:6: warning: 'void f1()' is not marked thread-safe. - void f1 [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In function 'void f2()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:8:6: warning: 'void f2()' is marked thread-safe. - void f2 [[gnu::thread_safe_debug]] [[gnu::thread_safe]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: At global scope: -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:13:8: warning: 'void C1::g1()' is not marked thread-safe. - void g1 [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:14:8: warning: 'void C1::g2()' is not marked thread-safe. - void g2 [[gnu::thread_safe_debug]] (); - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:16:8: warning: 'void C1::g4()' is marked thread-safe. - void g4 [[gnu::thread_safe]] [[gnu::thread_safe_debug]] (); - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In member function 'void C1::g2()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:20:6: warning: 'void C1::g2()' is not marked thread-safe. - void C1::g2() {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In member function 'void C1::g3()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:21:6: warning: 'void C1::g3()' is not marked thread-safe. - void C1::g3 [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In member function 'void C1::g4()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:22:6: warning: 'void C1::g4()' is marked thread-safe. - void C1::g4() {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: At global scope: -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:27:8: warning: 'void C2::h1()' is marked thread-safe. - void h1 [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In member function 'void C2::h2()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:35:6: warning: 'void C2::h2()' is marked thread-safe. - void C2::h2 [[gnu::thread_safe_debug]] () {} - ^ -/home/sss/atlas/rootaccess/../test/ists1_test.cxx: In member function 'void C2::C3::h3()': -/home/sss/atlas/rootaccess/../test/ists1_test.cxx:36:6: warning: 'void C2::C3::h3()' is marked thread-safe. - void C2::C3::h3 [[gnu::thread_safe_debug]] () {} - ^ diff --git a/External/CheckerGccPlugins/share/thread1_test.ref b/External/CheckerGccPlugins/share/thread1_test.ref index c4d26c8995921b1087a08b27fdb6f0e1961eecb3..669105b239de19427b8b48546e554e580eb21645 100644 --- a/External/CheckerGccPlugins/share/thread1_test.ref +++ b/External/CheckerGccPlugins/share/thread1_test.ref @@ -1,105 +1,105 @@ -../test/thread1_test.cxx: In function 'int f1(int)': -../test/thread1_test.cxx:9:9: warning: Use of static expression 'x' within thread-safe function 'int f1(int)' may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In function 'int f1(int)': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:9:5: warning: Use of static expression 'x' within function 'int f1(int)' may not be thread-safe. x = xx; - ^ -../test/thread1_test.cxx:8:14: note: Declared here: + ~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:8:14: note: Declared here: static int x; ^ -../test/thread1_test.cxx:9:9: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:9:5: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. x = xx; - ^ -../test/thread1_test.cxx:10:10: warning: Use of static expression 'x' within thread-safe function 'int f1(int)' may not be thread-safe. + ~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:10:10: warning: Use of static expression 'x' within function 'int f1(int)' may not be thread-safe. return x; ^ -../test/thread1_test.cxx:8:14: note: Declared here: +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:8:14: note: Declared here: static int x; ^ -../test/thread1_test.cxx:10:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:10:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return x; ^ -../test/thread1_test.cxx: In function 'int g1()': -../test/thread1_test.cxx:56:10: warning: Use of static expression 'y1' within thread-safe function 'int g1()' may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In function 'int g1()': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:10: warning: Use of static expression 'y1' within function 'int g1()' may not be thread-safe. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx:46:12: note: Declared here: + ~~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:60:12: note: Declared here: static int y1; - ^ -../test/thread1_test.cxx:56:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx:56:25: warning: Use of static expression 'yy1.Y::y1' within thread-safe function 'int g1()' may not be thread-safe. + ~~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:31: warning: Use of static expression 'yy1.Y::y1' within function 'int g1()' may not be thread-safe. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx:44:10: note: Declared here: + ~~~~^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:58:10: note: Declared here: static Y yy1; - ^ -../test/thread1_test.cxx:56:25: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:31: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx:56:40: warning: Use of static expression 'y5[5]' within thread-safe function 'int g1()' may not be thread-safe. + ~~~~^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:40: warning: Use of static expression 'y5[5]' within function 'int g1()' may not be thread-safe. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx:50:12: note: Declared here: + ~~~~^ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:64:12: note: Declared here: static int y5[10]; - ^ -../test/thread1_test.cxx:56:40: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:70:40: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. a = y1 + y2 + y3 + y4 + yy1.y1 + y5[5]; - ^ -../test/thread1_test.cxx: In function 'void g2(int)': -../test/thread1_test.cxx:63:9: warning: Use of static expression 'y1' within thread-safe function 'void g2(int)' may not be thread-safe. + ~~~~^ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In function 'void g2(int)': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:77:6: warning: Use of static expression 'y1' within function 'void g2(int)' may not be thread-safe. y1 = x; - ^ -../test/thread1_test.cxx:46:12: note: Declared here: + ~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:60:12: note: Declared here: static int y1; - ^ -../test/thread1_test.cxx:63:9: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:77:6: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. y1 = x; - ^ -../test/thread1_test.cxx:67:13: warning: Use of static expression 'yy1.Y::y2' within thread-safe function 'void g2(int)' may not be thread-safe. + ~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:81:10: warning: Use of static expression 'yy1.Y::y2' within function 'void g2(int)' may not be thread-safe. yy1.y2 = x; - ^ -../test/thread1_test.cxx:44:10: note: Declared here: + ~~~~~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:58:10: note: Declared here: static Y yy1; - ^ -../test/thread1_test.cxx:67:13: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:81:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. yy1.y2 = x; - ^ -../test/thread1_test.cxx:68:12: warning: Use of static expression 'y5[4]' within thread-safe function 'void g2(int)' may not be thread-safe. + ~~~~~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:82:9: warning: Use of static expression 'y5[4]' within function 'void g2(int)' may not be thread-safe. y5[4] = x; - ^ -../test/thread1_test.cxx:50:12: note: Declared here: + ~~~~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:64:12: note: Declared here: static int y5[10]; - ^ -../test/thread1_test.cxx:68:12: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:82:9: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. y5[4] = x; - ^ -../test/thread1_test.cxx: In function 'int g3(int)': -../test/thread1_test.cxx:74:23: warning: Use of static expression 'y1' within thread-safe function 'int g3(int)' may not be thread-safe. + ~~~~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In function 'int g3(int)': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:88:16: warning: Use of static expression 'y1' within function 'int g3(int)' may not be thread-safe. return (x>0) ? y1 : y2; - ^ -../test/thread1_test.cxx:46:12: note: Declared here: + ~~~~~~^~~~~~~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:60:12: note: Declared here: static int y1; - ^ -../test/thread1_test.cxx:74:23: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:88:16: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return (x>0) ? y1 : y2; - ^ -../test/thread1_test.cxx: In member function 'int H::hee1()': -../test/thread1_test.cxx:93:10: warning: Use of static expression 'H::h1' within thread-safe function 'int H::hee1()' may not be thread-safe. + ~~~~~~^~~~~~~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In member function 'int H::hee1()': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:107:10: warning: Use of static expression 'H::h1' within function 'int H::hee1()' may not be thread-safe. a = h1 + h2 + h3 + h4; - ^ -../test/thread1_test.cxx:80:14: note: Declared here: + ~~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:94:14: note: Declared here: static int h1; - ^ -../test/thread1_test.cxx:93:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:107:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. a = h1 + h2 + h3 + h4; - ^ -../test/thread1_test.cxx: In member function 'void H::hee2(int)': -../test/thread1_test.cxx:100:9: warning: Use of static expression 'H::h1' within thread-safe function 'void H::hee2(int)' may not be thread-safe. + ~~~^~~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx: In member function 'void H::hee2(int)': +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:114:6: warning: Use of static expression 'H::h1' within function 'void H::hee2(int)' may not be thread-safe. h1 = x; - ^ -../test/thread1_test.cxx:80:14: note: Declared here: + ~~~^~~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:94:14: note: Declared here: static int h1; - ^ -../test/thread1_test.cxx:100:9: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread1_test.cxx:114:6: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. h1 = x; - ^ + ~~~^~~ diff --git a/External/CheckerGccPlugins/share/thread2_test.ref b/External/CheckerGccPlugins/share/thread2_test.ref index 310af5e8c575cc4372be573c5cb766d4f81d44da..e3891a5f9000828bfe306c97964495d16ca6c7c5 100644 --- a/External/CheckerGccPlugins/share/thread2_test.ref +++ b/External/CheckerGccPlugins/share/thread2_test.ref @@ -1,40 +1,40 @@ -../test/thread2_test.cxx: In function 'int* f1()': -../test/thread2_test.cxx:13:11: warning: Pointer or reference bound to static expression 'y1' within thread-safe function 'int* f1()'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread2_test.cxx: In function 'int* f1()': +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:15:11: warning: Pointer or reference bound to static expression 'y1' within function 'int* f1()'; may not be thread-safe. return &y1; - ^ -../test/thread2_test.cxx:6:12: note: Declared here: + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:6:12: note: Declared here: static int y1; - ^ -../test/thread2_test.cxx:13:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:15:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return &y1; - ^ -../test/thread2_test.cxx: In function 'const int* f2()': -../test/thread2_test.cxx:19:11: warning: Pointer or reference bound to static expression 'y1' within thread-safe function 'const int* f2()'; may not be thread-safe. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx: In function 'const int* f2()': +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:21:11: warning: Pointer or reference bound to static expression 'y1' within function 'const int* f2()'; may not be thread-safe. return &y1; - ^ -../test/thread2_test.cxx:6:12: note: Declared here: + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:6:12: note: Declared here: static int y1; - ^ -../test/thread2_test.cxx:19:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:21:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return &y1; - ^ -../test/thread2_test.cxx: In function 'int& f3()': -../test/thread2_test.cxx:25:10: warning: Pointer or reference bound to static expression 'y1' within thread-safe function 'int& f3()'; may not be thread-safe. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx: In function 'int& f3()': +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:27:10: warning: Pointer or reference bound to static expression 'y1' within function 'int& f3()'; may not be thread-safe. return y1; - ^ -../test/thread2_test.cxx:6:12: note: Declared here: + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:6:12: note: Declared here: static int y1; - ^ -../test/thread2_test.cxx:25:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:27:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return y1; - ^ -../test/thread2_test.cxx: In function 'const int& f4()': -../test/thread2_test.cxx:31:10: warning: Pointer or reference bound to static expression 'y1' within thread-safe function 'const int& f4()'; may not be thread-safe. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx: In function 'const int& f4()': +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:33:10: warning: Pointer or reference bound to static expression 'y1' within function 'const int& f4()'; may not be thread-safe. return y1; - ^ -../test/thread2_test.cxx:6:12: note: Declared here: + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:6:12: note: Declared here: static int y1; - ^ -../test/thread2_test.cxx:31:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread2_test.cxx:33:10: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. return y1; - ^ + ^~ diff --git a/External/CheckerGccPlugins/share/thread3_test.ref b/External/CheckerGccPlugins/share/thread3_test.ref index 06161b07ccb81578ef8cb4fbcf78939a1fb15d98..b5e54c83bda932ed7c0b35d71202dd273b02ed1f 100644 --- a/External/CheckerGccPlugins/share/thread3_test.ref +++ b/External/CheckerGccPlugins/share/thread3_test.ref @@ -1,38 +1,38 @@ /home/sss/atlas/rootaccess/../test/thread3_test.cxx: In function 'void f1()': -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:18:15: warning: Static expression 'y1' passed to pointer or reference function argument within thread-safe function 'void f1()'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:19:15: warning: Static expression 'y1' passed to pointer or reference function argument within function 'void f1()'; may not be thread-safe. foo1(3, &y1); ^ /home/sss/atlas/rootaccess/../test/thread3_test.cxx:6:12: note: Declared here: static int y1; - ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:18:15: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:19:15: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. foo1(3, &y1); ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:19:14: warning: Static expression 'y1' passed to pointer or reference function argument within thread-safe function 'void f1()'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:20:14: warning: Static expression 'y1' passed to pointer or reference function argument within function 'void f1()'; may not be thread-safe. foo2(3, y1); ^ /home/sss/atlas/rootaccess/../test/thread3_test.cxx:6:12: note: Declared here: static int y1; - ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:19:14: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:20:14: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. foo2(3, y1); ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:20:15: warning: Static expression 'y1' passed to pointer or reference function argument within thread-safe function 'void f1()'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:21:15: warning: Static expression 'y1' passed to pointer or reference function argument within function 'void f1()'; may not be thread-safe. foo3(3, &y1); ^ /home/sss/atlas/rootaccess/../test/thread3_test.cxx:6:12: note: Declared here: static int y1; - ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:20:15: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:21:15: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. foo3(3, &y1); ^ /home/sss/atlas/rootaccess/../test/thread3_test.cxx: In function 'void f2()': -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:38:11: warning: Static expression 'c1' passed to pointer or reference function argument within thread-safe function 'void f2()'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:40:11: warning: Static expression 'c1' passed to pointer or reference function argument within function 'void f2()'; may not be thread-safe. c1.foo(); ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:33:10: note: Declared here: +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:35:10: note: Declared here: static C c1; - ^ -/home/sss/atlas/rootaccess/../test/thread3_test.cxx:38:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. + ^~ +/home/sss/atlas/rootaccess/../test/thread3_test.cxx:40:11: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. c1.foo(); ^ diff --git a/External/CheckerGccPlugins/share/thread4_test.ref b/External/CheckerGccPlugins/share/thread4_test.ref index fa1dd12870681b92763886c4df7050c00e5c8ea2..78115da5dd289dd8b8641551921a95089a3a6a55 100644 --- a/External/CheckerGccPlugins/share/thread4_test.ref +++ b/External/CheckerGccPlugins/share/thread4_test.ref @@ -1,25 +1,40 @@ /home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f1(const int*)': -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:7:28: warning: Const discarded from expression 'y' within thread-safe function 'int* f1(const int*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:10:28: warning: Const discarded from expression 'y' within function 'int* f1(const int*)'; may not be thread-safe. return const_cast<int*>(y); ^ -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:7:28: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:10:28: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f2(const int*)': -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:13:18: warning: Const discarded from expression 'y' within thread-safe function 'int* f2(const int*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:16:18: warning: Const discarded from expression 'y' within function 'int* f2(const int*)'; may not be thread-safe. return (int*)(y); ^ -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:13:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:16:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f3(const int*)': -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:19:22: warning: Const discarded from expression 'y' within thread-safe function 'int* f3(const int*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:22:22: warning: Const discarded from expression 'y' within function 'int* f3(const int*)'; may not be thread-safe. return (int*)(&y[5]); ^ -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:19:22: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:22:22: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f4(const S&)': -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:30:31: warning: Const discarded from expression '&*s.S::x' within thread-safe function 'int* f4(const S&)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:33:31: warning: Const discarded from expression '&*s.S::x' (deriving from parameter 's') within function 'int* f4(const S&)'; may not be thread-safe. return &const_cast<int&>(s.x); ^ -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:30:31: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:33:31: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f5(S*)': -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:35:20: warning: Const discarded from expression '&*s.S::y' within thread-safe function 'int* f5(S*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:38:20: warning: Const discarded from expression '&*s.S::y' (deriving from parameter 's') within function 'int* f5(S*)'; may not be thread-safe. return (int*)&s->y; ^ -/home/sss/atlas/rootaccess/../test/thread4_test.cxx:35:20: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:38:20: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f7(const int*)': +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:53:30: warning: Const discarded from expression 'yyy' (deriving from parameter 'y') within function 'int* f7(const int*)'; may not be thread-safe. + return const_cast<int*>(yyy); + ^ +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:53:30: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f8a(const int*)': +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:68:30: warning: Const discarded from expression 'yyy' (deriving from parameter 'y') within function 'int* f8a(const int*)'; may not be thread-safe. + return const_cast<int*>(yyy); + ^ +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:68:30: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread4_test.cxx: In function 'int* f9a()': +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:82:28: warning: Const discarded from expression 'y' within function 'int* f9a()'; may not be thread-safe. + return const_cast<int*>(y); + ^ +/home/sss/atlas/rootaccess/../test/thread4_test.cxx:82:28: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. diff --git a/External/CheckerGccPlugins/share/thread5_test.ref b/External/CheckerGccPlugins/share/thread5_test.ref index 8659a33f4e1385e985140895f48eb8027e2c7c80..b2f9522f15a6c8a3b1e8264d1c0507f48c2ef478 100644 --- a/External/CheckerGccPlugins/share/thread5_test.ref +++ b/External/CheckerGccPlugins/share/thread5_test.ref @@ -1,20 +1,30 @@ /home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f2(const int*)': -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:8:26: warning: Const discarded from expression 'y' in call from thread-safe function 'void f2(const int*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:9:26: warning: Const discarded from expression 'y' within function 'void f2(const int*)'; may not be thread-safe. f1(const_cast<int*>(y)); ^ -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:8:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:9:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f3(const int*)': -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:13:18: warning: Const discarded from expression '<unknown>' in call from thread-safe function 'void f3(const int*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:14:18: warning: Const discarded from expression '<unknown>' (deriving from parameter 'y') within function 'void f3(const int*)'; may not be thread-safe. f1((int*)&y[5]); ^ -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:13:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:14:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f4(const S*)': -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:25:18: warning: Const discarded from expression '<unknown>' in call from thread-safe function 'void f4(const S*)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:26:18: warning: Const discarded from expression '<unknown>' (deriving from parameter 's') within function 'void f4(const S*)'; may not be thread-safe. f1((int*)&s->x); ^ -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:25:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:26:18: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. /home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f6(const S&)': -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:37:26: warning: Const discarded from expression 's' in call from thread-safe function 'void f6(const S&)'; may not be thread-safe. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:38:26: warning: Const discarded from expression 's' within function 'void f6(const S&)'; may not be thread-safe. const_cast<S&>(s).foo(); ^ -/home/sss/atlas/rootaccess/../test/thread5_test.cxx:37:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:38:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f7a(const int*)': +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:48:26: warning: Const discarded from expression 'y' within function 'void f7a(const int*)'; may not be thread-safe. + f1(const_cast<int*>(y)); + ^ +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:48:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread5_test.cxx: In function 'void f8a()': +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:60:26: warning: Const discarded from expression 'y' within function 'void f8a()'; may not be thread-safe. + f1(const_cast<int*>(y)); + ^ +/home/sss/atlas/rootaccess/../test/thread5_test.cxx:60:26: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. diff --git a/External/CheckerGccPlugins/share/thread8_test.ref b/External/CheckerGccPlugins/share/thread8_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..e65c7064219ee247d7224febf9cb9e3d95fcbe0e --- /dev/null +++ b/External/CheckerGccPlugins/share/thread8_test.ref @@ -0,0 +1,15 @@ +/home/sss/atlas/rootaccess/../test/thread8_test.cxx: In function 'int* f1()': +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:10:31: warning: Const discarded from expression 'xx' within function 'int* f1()'; may not be thread-safe. + return const_cast<int*>(xx()); + ^ +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:10:31: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread8_test.cxx: In function 'int* f2()': +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:16:33: warning: Const discarded from expression 'xx' within function 'int* f2()'; may not be thread-safe. + int* y = const_cast<int*>(xx()); + ^ +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:16:33: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. +/home/sss/atlas/rootaccess/../test/thread8_test.cxx: In function 'int* f5()': +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:37:33: warning: Const discarded from expression 'xx' within function 'int* f5()'; may not be thread-safe. + int* y = const_cast<int*>(xx()); + ^ +/home/sss/atlas/rootaccess/../test/thread8_test.cxx:37:33: note: See <https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CheckerGccPlugins#thread_plugin>. diff --git a/External/CheckerGccPlugins/src/is_thread_safe.cxx b/External/CheckerGccPlugins/src/check_thread_safety_p.cxx similarity index 72% rename from External/CheckerGccPlugins/src/is_thread_safe.cxx rename to External/CheckerGccPlugins/src/check_thread_safety_p.cxx index 0ae3b727fc053cb7fef7950ce20fb66559854b7d..b17f522d373a8150b60cb2f4731f90fe4ce7074c 100644 --- a/External/CheckerGccPlugins/src/is_thread_safe.cxx +++ b/External/CheckerGccPlugins/src/check_thread_safety_p.cxx @@ -1,9 +1,21 @@ // $Id$ /** - * @file CheckerGccPlugins/src/is_thread_safe.cxx + * @file CheckerGccPlugins/src/check_thread_safety_p.cxx * @author scott snyder <snyder@bnl.gov> * @date Sep, 2015 - * @brief Test to see if something has been declared as thread-safe. + * @brief Test to see if something should be checked for thread-safety. + * + * check_thread_safety_p(decl) returns false if DECL has a not_thread_safe + * attribute. Otherwise, it returns true in the following cases: + * + * - DECL directly has a check_thread_safety attribute. + * - DECL is a function or type and a containing context has thread-safety + * checking on. + * - The file contains #pragma ATLAS check_thread_safety. + * - The package contains a file ATLAS_CHECK_THREAD_SAFETY. + * + * If a decl has the attribute check_thread_safety_debug, then a diagnostic + * will be printed saying if that decl has thread-safety checking enabled. */ @@ -28,10 +40,10 @@ void thread_safe_debug_finishdecl_callback (void* gcc_data, void* /*user_data*/) if (!loc) return; if (!seen_loc.insert (loc).second) return; - if (lookup_attribute ("thread_safe_debug", DECL_ATTRIBUTES (decl))) + if (lookup_attribute ("check_thread_safety_debug", DECL_ATTRIBUTES (decl))) { const char* flag = " not"; - if (CheckerGccPlugins::is_thread_safe (decl)) + if (CheckerGccPlugins::check_thread_safety_p (decl)) flag = ""; warning_at (DECL_SOURCE_LOCATION (decl), 0, "%<%D%> is%s marked thread-safe.", decl, flag); @@ -108,7 +120,7 @@ namespace CheckerGccPlugins { bool is_thread_safe_dir (const std::string& dir, int nwalk = 5); bool is_thread_safe_dir1 (const std::string& dir, int nwalk = 5) { - std::string flagfile = dir + "/ATLAS_THREAD_SAFE"; + std::string flagfile = dir + "/ATLAS_CHECK_THREAD_SAFETY"; if (access (flagfile.c_str(), R_OK) == 0) return true; @@ -140,7 +152,7 @@ bool is_thread_safe_dir (const std::string& dir, int nwalk /*= 5*/) } -bool is_thread_safe_location (location_t loc) +bool check_thread_safety_location_p (location_t loc) { std::string file = LOCATION_FILE(loc); thread_safe_files_t::iterator it = thread_safe_files.find (file); @@ -157,11 +169,13 @@ bool is_thread_safe_location (location_t loc) } -/// Has DECL been declared thread-safe? -bool is_thread_safe (tree decl) +/// Has DECL been declared for thread-safety checking? +bool check_thread_safety_p (tree decl) { - // Check if the attribute is present directly. - if (lookup_attribute ("thread_safe", DECL_ATTRIBUTES (decl))) + // Check if attributes are present directly. + if (lookup_attribute ("not_thread_safe", DECL_ATTRIBUTES (decl))) + return false; + if (lookup_attribute ("check_thread_safety", DECL_ATTRIBUTES (decl))) return true; // If it's a function or class, check the containing function or class. @@ -171,17 +185,17 @@ bool is_thread_safe (tree decl) tree ctx = DECL_CONTEXT (decl); while (ctx && !SCOPE_FILE_SCOPE_P (ctx)) { if (TREE_CODE (ctx) == RECORD_TYPE) { - if (lookup_attribute ("thread_safe", TYPE_ATTRIBUTES (ctx))) + if (lookup_attribute ("check_thread_safety", TYPE_ATTRIBUTES (ctx))) return true; - if (is_thread_safe_location (DECL_SOURCE_LOCATION (TYPE_NAME (ctx)))) + if (check_thread_safety_location_p (DECL_SOURCE_LOCATION (TYPE_NAME (ctx)))) return true; ctx = TYPE_CONTEXT (ctx); } else if (TREE_CODE (ctx) == FUNCTION_DECL) { - if (lookup_attribute ("thread_safe", DECL_ATTRIBUTES (ctx))) + if (lookup_attribute ("check_thread_safety", DECL_ATTRIBUTES (ctx))) return true; - if (is_thread_safe_location (DECL_SOURCE_LOCATION (ctx))) + if (check_thread_safety_location_p (DECL_SOURCE_LOCATION (ctx))) return true; ctx = DECL_CONTEXT (ctx); } @@ -192,14 +206,14 @@ bool is_thread_safe (tree decl) } // Check the file in which it was declared. - if (is_thread_safe_location (DECL_SOURCE_LOCATION (decl))) + if (check_thread_safety_location_p (DECL_SOURCE_LOCATION (decl))) return true; return false; } -void handle_thread_safe_pragma (cpp_reader*) +void handle_check_thread_safety_pragma (cpp_reader*) { thread_safe_files[LOCATION_FILE (input_location)] = true; } diff --git a/External/CheckerGccPlugins/src/checker_gccplugins.cxx b/External/CheckerGccPlugins/src/checker_gccplugins.cxx index e979b39ce7cfb8964f54e9f5554fc4941333e61c..2c580c759e9242e8c678d02dda8c8958abdc1d07 100644 --- a/External/CheckerGccPlugins/src/checker_gccplugins.cxx +++ b/External/CheckerGccPlugins/src/checker_gccplugins.cxx @@ -167,7 +167,12 @@ checker_plugin_info = { static struct attribute_spec attribs[] = { {"thread_safe", 0, 0, false, false, false, NULL, false}, - {"thread_safe_debug", 0, 0, false, false, false, NULL, false}, + {"not_thread_safe", 0, 0, false, false, false, NULL, false}, + {"not_reentrant", 0, 0, false, false, false, NULL, false}, + {"not_const_thread_safe", 0, 0, false, false, false, NULL, false}, + {"argument_not_const_thread_safe", 0, 0, false, false, false, NULL, false}, + {"check_thread_safety", 0, 0, false, false, false, NULL, false}, + {"check_thread_safety_debug", 0, 0, false, false, false, NULL, false}, {NULL, 0, 0, false, false, false, NULL, false}, }; @@ -185,8 +190,8 @@ static void register_checker_pragmas (void* /*event_data*/, void* /*data*/) { - c_register_pragma ("ATLAS", "thread_safe", - CheckerGccPlugins::handle_thread_safe_pragma); + c_register_pragma ("ATLAS", "check_thread_safety", + CheckerGccPlugins::handle_check_thread_safety_pragma); } diff --git a/External/CheckerGccPlugins/src/checker_gccplugins.h b/External/CheckerGccPlugins/src/checker_gccplugins.h index 7a527c4f97a862aac1d61efea283c7d3cb954dce..d916be79e1623a49d5d8e5db1bbd18a505ec43ee 100644 --- a/External/CheckerGccPlugins/src/checker_gccplugins.h +++ b/External/CheckerGccPlugins/src/checker_gccplugins.h @@ -33,11 +33,11 @@ namespace CheckerGccPlugins { /// Has DECL been declared thread-safe? -bool is_thread_safe (tree decl); +bool check_thread_safety_p (tree decl); -bool is_thread_safe_location (location_t loc); +bool check_thread_safety_location_p (location_t loc); -void handle_thread_safe_pragma (cpp_reader*); +void handle_check_thread_safety_pragma (cpp_reader*); void inform_url (location_t loc, const char* url); diff --git a/External/CheckerGccPlugins/src/gaudi_inheritance_plugin.cxx b/External/CheckerGccPlugins/src/gaudi_inheritance_plugin.cxx index 40c08cb6fb32ca9c1d43145942c55d183d919fd4..af735295d2f2041012fbb4404405a36585b9bf33 100644 --- a/External/CheckerGccPlugins/src/gaudi_inheritance_plugin.cxx +++ b/External/CheckerGccPlugins/src/gaudi_inheritance_plugin.cxx @@ -59,7 +59,11 @@ void type_callback (void* gcc_data, void* /*user_data*/) tree t = (tree)gcc_data; tree tt = t;//TYPE_MAIN_VARIANT(t); if (TREE_CODE(tt) != RECORD_TYPE || +#if defined(GCC_VERSION) && (GCC_VERSION >= 7000) + TYPE_UNNAMED_P(tt) || +#else TYPE_ANONYMOUS_P(tt) || +#endif !COMPLETE_TYPE_P(tt)) { return; diff --git a/External/CheckerGccPlugins/src/static_plugin.cxx b/External/CheckerGccPlugins/src/static_plugin.cxx index 3ed3d02d8add70f0353eee1cb08c6f0b08a33654..f4f0d6355a113bab191942058b62e2630bf54df7 100644 --- a/External/CheckerGccPlugins/src/static_plugin.cxx +++ b/External/CheckerGccPlugins/src/static_plugin.cxx @@ -70,8 +70,8 @@ void static_finishdecl_callback (void* gcc_data, void* /*user_data*/) tree ctxdecl = ctx; if (TYPE_P (ctxdecl)) ctxdecl = TYPE_NAME (ctxdecl); - if (!is_thread_safe (decl) && - !is_thread_safe_location (DECL_SOURCE_LOCATION (decl))) + if (!check_thread_safety_p (decl) && + !check_thread_safety_location_p (DECL_SOURCE_LOCATION (decl))) { return; } diff --git a/External/CheckerGccPlugins/src/thread_plugin.cxx b/External/CheckerGccPlugins/src/thread_plugin.cxx index be4987b745dc219fbf91dc1d62cf446d6a1fa050..bd9512f3d895a664c013f03db5733552f3f7ada0 100644 --- a/External/CheckerGccPlugins/src/thread_plugin.cxx +++ b/External/CheckerGccPlugins/src/thread_plugin.cxx @@ -241,15 +241,31 @@ tree get_inner (tree expr) #if GCC_VERSION >= 6000 &preversep, #endif - &pvolatilep, false); + &pvolatilep +#if GCC_VERSION < 7000 + , false +#endif + ); } return expr; } +bool has_attrib (tree decl, const char* attrname) +{ + return lookup_attribute (attrname, DECL_ATTRIBUTES (decl)); +} + + +bool has_attrib (function* fun, const char* attrname) +{ + return lookup_attribute (attrname, DECL_ATTRIBUTES (fun->decl)); +} + + bool has_thread_safe_attrib (tree decl) { - return lookup_attribute ("thread_safe", DECL_ATTRIBUTES (decl)); + return has_attrib (decl, "thread_safe"); } @@ -307,15 +323,17 @@ void check_mutable (tree expr, gimplePtr stmt, function* fun, const char* what) // Check for direct use of a static value. void check_direct_static_use (gimplePtr stmt, function* fun) { + if (has_attrib (fun, "not_reentrant")) + return; + size_t nop = gimple_num_ops (stmt); for (size_t i = 0; i < nop; i++) { tree op = gimple_op (stmt, i); - //debug_tree (op); tree optest = get_inner (op); if (static_p (optest)) { warning_at (gimple_location (stmt), 0, - "Use of static expression %<%E%> within thread-safe function %<%D%> may not be thread-safe.", + "Use of static expression %<%E%> within function %<%D%> may not be thread-safe.", op, fun->decl); if (DECL_P (optest)) { inform (DECL_SOURCE_LOCATION (optest), @@ -329,7 +347,122 @@ void check_direct_static_use (gimplePtr stmt, function* fun) // Check for assigning from an address of a static object // into a pointer/reference, or for discarding const. -void check_assign_address_of_static (gimplePtr stmt, function* fun) +// OP: operand to check +// STMT: gimple statement being checked +// FUN: function being checked +void check_assign_address_of_static (tree op, gimplePtr stmt, function* fun) +{ + if (op && TREE_CODE (op) == ADDR_EXPR) { + while (op && TREE_CODE (op) == ADDR_EXPR) + op = TREE_OPERAND (op, 0); + } + + tree optest = get_inner (op); + if (static_p (optest) && !has_attrib (fun, "not_reentrant")) { + warning_at (gimple_location (stmt), 0, + "Pointer or reference bound to static expression %<%E%> within function %<%D%>; may not be thread-safe.", + op, fun->decl); + if (DECL_P (optest)) { + inform (DECL_SOURCE_LOCATION (optest), + "Declared here:"); + } + CheckerGccPlugins::inform_url (gimple_location (stmt), url); + } +} + + +// Test to see if a pointer value comes directly or indirectly from +// a const pointer function argument. +tree pointer_is_const_arg (tree val) +{ + //fprintf (stderr, "pointer_is_const_arg_p\n"); + //debug_tree(val); + tree valtest = get_inner (val); + tree valtype = TREE_TYPE (valtest); + if (!POINTER_TYPE_P(valtype) || !TYPE_READONLY (TREE_TYPE (valtype))) + return NULL_TREE; + + if (TREE_CODE (val) == ADDR_EXPR) + val = TREE_OPERAND (val, 0); + if (TREE_CODE (val) == COMPONENT_REF) + val = get_inner (val); + if (TREE_CODE (val) == MEM_REF) + val = TREE_OPERAND (val, 0); + + if (TREE_CODE (val) != SSA_NAME) return NULL_TREE; + if (SSA_NAME_VAR (val) && TREE_CODE (SSA_NAME_VAR (val)) == PARM_DECL) return val; + + gimplePtr stmt = SSA_NAME_DEF_STMT (val); + if (!stmt) return NULL_TREE; + //debug_gimple_stmt (stmt); + //fprintf (stderr, "code %s\n", get_tree_code_name(gimple_expr_code(stmt))); + + if (is_gimple_assign (stmt) && (gimple_expr_code(stmt) == VAR_DECL || + gimple_expr_code(stmt) == PARM_DECL || + gimple_expr_code(stmt) == POINTER_PLUS_EXPR || + gimple_expr_code(stmt) == ADDR_EXPR)) + { + //fprintf (stderr, "recurse\n"); + return pointer_is_const_arg (gimple_op(stmt, 1)); + } + else if (gimple_code (stmt) == GIMPLE_PHI) { + size_t nop = gimple_num_ops (stmt); + for (size_t i = 0; i < nop; i++) { + tree op = gimple_op (stmt, i); + tree ret = pointer_is_const_arg (op); + if (ret) return ret; + } + } + return NULL_TREE; +} + + +void warn_about_discarded_const (tree expr, gimplePtr stmt, function* fun) +{ + tree parm = pointer_is_const_arg (expr); + if (parm) { + if (has_attrib (fun, "argument_not_const_thread_safe")) return; + if (expr == parm) { + warning_at (gimple_location (stmt), 0, + "Const discarded from expression %<%E%> within function %<%D%>; may not be thread-safe.", + expr, fun->decl); + } + else { + warning_at (gimple_location (stmt), 0, + "Const discarded from expression %<%E%> (deriving from parameter %<%E%>) within function %<%D%>; may not be thread-safe.", + expr, parm, fun->decl); + } + } + else { + if (has_attrib (fun, "not_const_thread_safe")) return; + warning_at (gimple_location (stmt), 0, + "Const discarded from expression %<%E%> within function %<%D%>; may not be thread-safe.", + expr, fun->decl); + } + CheckerGccPlugins::inform_url (gimple_location (stmt), url); +} + + +// Called when LHS does not have const type. +void check_discarded_const (tree op, tree lhs, gimplePtr stmt, function* fun) +{ + tree optest = get_inner (op); + tree optype = TREE_TYPE (optest); + if (POINTER_TYPE_P(optype) && TYPE_READONLY (TREE_TYPE (optype))) { + if (TREE_CODE (lhs) == SSA_NAME && + SSA_NAME_VAR (lhs) && + has_thread_safe_attrib (SSA_NAME_VAR (lhs))) + { + // Allow const_cast if LHS is explicitly marked thread_safe. + } + else { + warn_about_discarded_const (op, stmt, fun); + } + } +} + + +void check_assignments (gimplePtr stmt, function* fun) { if (gimple_code (stmt) != GIMPLE_ASSIGN) return; size_t nop = gimple_num_ops (stmt); @@ -351,25 +484,10 @@ void check_assign_address_of_static (gimplePtr stmt, function* fun) // Check for discarding const if LHS is non-const. if (!lhs_const) - { - tree optest = get_inner (op); - tree optype = TREE_TYPE (optest); - if (POINTER_TYPE_P(optype) && TYPE_READONLY (TREE_TYPE (optype))) { - if (TREE_CODE (lhs) == SSA_NAME && - SSA_NAME_VAR (lhs) && - has_thread_safe_attrib (SSA_NAME_VAR (lhs))) - { - // Allow const_cast if LHS is explicitly marked thread_safe. - } - else { - warning_at (gimple_location (stmt), 0, - "Const discarded from expression %<%E%> within thread-safe function %<%D%>; may not be thread-safe.", - op, fun->decl); - CheckerGccPlugins::inform_url (gimple_location (stmt), url); - } - } - } + check_discarded_const (op, lhs, stmt, fun); + check_assign_address_of_static (op, stmt, fun); + if (op && TREE_CODE (op) == ADDR_EXPR) { while (op && TREE_CODE (op) == ADDR_EXPR) op = TREE_OPERAND (op, 0); @@ -377,27 +495,13 @@ void check_assign_address_of_static (gimplePtr stmt, function* fun) if (!lhs_const) check_mutable (op, stmt, fun, "Taking non-const reference to mutable field"); - - { - tree optest = get_inner (op); - if (static_p (optest)) { - warning_at (gimple_location (stmt), 0, - "Pointer or reference bound to static expression %<%E%> within thread-safe function %<%D%>; may not be thread-safe.", - op, fun->decl); - if (DECL_P (optest)) { - inform (DECL_SOURCE_LOCATION (optest), - "Declared here:"); - } - CheckerGccPlugins::inform_url (gimple_location (stmt), url); - } - } } } void check_thread_safe_call (tree fndecl, gimplePtr stmt, function* fun) { - if (is_thread_safe (fndecl)) return; + if (check_thread_safety_p (fndecl)) return; std::string fnname = decl_as_string (fndecl, TFF_SCOPE + TFF_NO_FUNCTION_ARGUMENTS); location_t loc = DECL_SOURCE_LOCATION (fndecl); @@ -420,10 +524,89 @@ void check_thread_safe_call (tree fndecl, gimplePtr stmt, function* fun) // Check passing an address of a static object to a called function // by non-const pointer/ref. -void check_pass_static_by_call (gimplePtr stmt, function* fun) +// ARG_TYPE: type of argument +// ARG: argument to test +// STMT: gimple statement being checked +// FUN: function being checked +void check_pass_static_by_call (tree arg_type, tree arg, gimplePtr stmt, function* fun) +{ + if (!POINTER_TYPE_P (arg_type)) return; + + if (arg && TREE_CODE (arg) == ADDR_EXPR) { + while (arg && TREE_CODE (arg) == ADDR_EXPR) + arg = TREE_OPERAND (arg, 0); + } + tree argtest = get_inner (arg); + + if (static_p (argtest) && !has_attrib (fun, "not_reentrant")) { + warning_at (gimple_location (stmt), 0, + "Static expression %<%E%> passed to pointer or reference function argument within function %<%D%>; may not be thread-safe.", + arg, fun->decl); + if (DECL_P (argtest)) { + inform (DECL_SOURCE_LOCATION (argtest), + "Declared here:"); + } + CheckerGccPlugins::inform_url (gimple_location (stmt), url); + } +} + + +// Check for discarding const from a pointer/ref in a function call. +// ARG_TYPE: type of argument +// ARG: argument to test +// STMT: gimple statement being checked +// FUN: function being checked +void check_discarded_const_in_funcall (tree arg_type, tree arg, gimplePtr stmt, function* fun) +{ + bool lhs_const = TYPE_READONLY (TREE_TYPE (arg_type)); + + tree argtest = get_inner (arg); + + tree ctest = TREE_TYPE (argtest); + if (POINTER_TYPE_P (ctest)) + ctest = TREE_TYPE (ctest); + + if (!lhs_const && ctest && TYPE_READONLY (ctest)) + { + warn_about_discarded_const (arg, stmt, fun); + } +} + + +// Check for discarding const from the return value of a function. +// STMT: gimple statement being checked +// FUN: function being checked +void check_discarded_const_from_return (gimplePtr stmt, function* fun) +{ + tree lhs = gimple_call_lhs (stmt); + if (!lhs) return; + tree lhs_type = TREE_TYPE (lhs); + if (!POINTER_TYPE_P (lhs_type)) return; + bool lhs_const = TYPE_READONLY (TREE_TYPE (lhs_type)); + if (lhs_const) return; + + if (TREE_CODE (lhs) == SSA_NAME && + SSA_NAME_VAR (lhs) && + has_thread_safe_attrib (SSA_NAME_VAR (lhs))) + return; + + tree rhs_type = gimple_expr_type (stmt); + if (POINTER_TYPE_P (rhs_type)) + rhs_type = TREE_TYPE (rhs_type); + + if (rhs_type && TYPE_READONLY (rhs_type)) + { + warn_about_discarded_const (gimple_call_fn(stmt), stmt, fun); + } +} + + +void check_calls (gimplePtr stmt, function* fun) { if (gimple_code (stmt) != GIMPLE_CALL) return; + check_discarded_const_from_return (stmt, fun); + tree fndecl = gimple_call_fndecl (stmt); if (fndecl) check_thread_safe_call (fndecl, stmt, fun); @@ -440,44 +623,21 @@ void check_pass_static_by_call (gimplePtr stmt, function* fun) tree arg = gimple_call_arg (stmt, i); if (!POINTER_TYPE_P (arg_type)) continue; - bool lhs_const = TYPE_READONLY (TREE_TYPE (arg_type)); if (arg && TREE_CODE (arg) == ADDR_EXPR) { while (arg && TREE_CODE (arg) == ADDR_EXPR) arg = TREE_OPERAND (arg, 0); } - tree argtest = get_inner (arg); - - tree ctest = TREE_TYPE (argtest); - if (POINTER_TYPE_P (ctest)) - ctest = TREE_TYPE (ctest); - - if (!lhs_const && ctest && TYPE_READONLY (ctest)) - { - warning_at (gimple_location (stmt), 0, - "Const discarded from expression %<%E%> in call from thread-safe function %<%D%>; may not be thread-safe.", - arg, fun->decl); - CheckerGccPlugins::inform_url (gimple_location (stmt), url); - } - - if (static_p (argtest)) { - warning_at (gimple_location (stmt), 0, - "Static expression %<%E%> passed to pointer or reference function argument within thread-safe function %<%D%>; may not be thread-safe.", - arg, fun->decl); - if (DECL_P (argtest)) { - inform (DECL_SOURCE_LOCATION (argtest), - "Declared here:"); - } - CheckerGccPlugins::inform_url (gimple_location (stmt), url); - } + check_discarded_const_in_funcall (arg_type, arg, stmt, fun); + check_pass_static_by_call (arg_type, arg, stmt, fun); } } unsigned int thread_pass::thread_execute (function* fun) { - if (!is_thread_safe (fun->decl)) + if (!check_thread_safety_p (fun->decl)) return 0; basic_block bb; @@ -490,8 +650,8 @@ unsigned int thread_pass::thread_execute (function* fun) //debug_gimple_stmt (stmt); check_direct_static_use (stmt, fun); - check_assign_address_of_static (stmt, fun); - check_pass_static_by_call (stmt, fun); + check_assignments (stmt, fun); + check_calls (stmt, fun); } } @@ -507,7 +667,7 @@ void thread_finishtype_callback (void* gcc_data, void* /*user_data*/) if (TREE_CODE (type) == RECORD_TYPE) { if (CP_AGGREGATE_TYPE_P (type)) return; tree decl = TYPE_NAME (type); - if (!is_thread_safe(decl)) return; + if (!check_thread_safety_p(decl)) return; for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f)) { if (TREE_CODE (f) == FIELD_DECL) { diff --git a/External/CheckerGccPlugins/test/Control/p1/ATLAS_THREAD_SAFE b/External/CheckerGccPlugins/test/Control/p1/ATLAS_CHECK_THREAD_SAFETY similarity index 100% rename from External/CheckerGccPlugins/test/Control/p1/ATLAS_THREAD_SAFE rename to External/CheckerGccPlugins/test/Control/p1/ATLAS_CHECK_THREAD_SAFETY diff --git a/External/CheckerGccPlugins/test/Control/p1/p1/p1a.h b/External/CheckerGccPlugins/test/Control/p1/p1/p1a.h index 9bbe76453cf206d36c3c20161027447677252273..6f82cb4aa55e499b89e12f551d40f7f0a3c6e27e 100644 --- a/External/CheckerGccPlugins/test/Control/p1/p1/p1a.h +++ b/External/CheckerGccPlugins/test/Control/p1/p1/p1a.h @@ -1 +1 @@ -void p1a [[gnu::thread_safe_debug]] () {} +void p1a [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/Control/p1/p1/p1b.h b/External/CheckerGccPlugins/test/Control/p1/p1/p1b.h index 602fafba9f6c93103a63cc7885bc33786142317e..f3459a76c7f2669c82ec8ed5a73fa58244d6be8a 100644 --- a/External/CheckerGccPlugins/test/Control/p1/p1/p1b.h +++ b/External/CheckerGccPlugins/test/Control/p1/p1/p1b.h @@ -1 +1 @@ -void p1b [[gnu::thread_safe_debug]] () {} +void p1b [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/Control/p2/p2/p2a.h b/External/CheckerGccPlugins/test/Control/p2/p2/p2a.h index c5e2e5142513c9243e25de6311fd9b672691d33b..73665d2ed59b4b0d2736a313be682d5634d70478 100644 --- a/External/CheckerGccPlugins/test/Control/p2/p2/p2a.h +++ b/External/CheckerGccPlugins/test/Control/p2/p2/p2a.h @@ -1 +1 @@ -void p2a [[gnu::thread_safe_debug]] () {} +void p2a [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/Control/p2/p2/p2b.h b/External/CheckerGccPlugins/test/Control/p2/p2/p2b.h index 37db0393a525fc87b52f43b626db8a6a1eeb26d3..ceda4d04dfd5c2ca053eb1e71b5cfbc900e02dd0 100644 --- a/External/CheckerGccPlugins/test/Control/p2/p2/p2b.h +++ b/External/CheckerGccPlugins/test/Control/p2/p2/p2b.h @@ -1 +1 @@ -void p2b [[gnu::thread_safe_debug]] () {} +void p2b [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/check_ts1_test.cxx b/External/CheckerGccPlugins/test/check_ts1_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0666a540176908bace8be52420387762bc3ba894 --- /dev/null +++ b/External/CheckerGccPlugins/test/check_ts1_test.cxx @@ -0,0 +1,39 @@ +#include "check_ts1_test1.h" +#include "Control/p1/p1/p1a.h" +#include "Control/p1/p1/p1b.h" +#include "Control/p2/p2/p2a.h" +#include "Control/p2/p2/p2b.h" + +void f1 [[gnu::check_thread_safety_debug]] () {} +void f2 [[gnu::check_thread_safety_debug]] [[gnu::check_thread_safety]] () {} + + +struct [[gnu::check_thread_safety_debug]] C1 +{ + void g1 [[gnu::check_thread_safety_debug]] () {} + void g2 [[gnu::check_thread_safety_debug]] (); + void g3(); + void g4 [[gnu::check_thread_safety]] [[gnu::check_thread_safety_debug]] (); + void g5 [[gnu::not_thread_safe]] [[gnu::check_thread_safety_debug]] (); +}; + + +void C1::g2() {} +void C1::g3 [[gnu::check_thread_safety_debug]] () {} +void C1::g4() {} + + +struct [[gnu::check_thread_safety]] C2 +{ + void h1 [[gnu::check_thread_safety_debug]] () {} + void h2(); + + struct C3 { + void h3(); + }; + + void h4 [[gnu::not_thread_safe]] [[gnu::check_thread_safety_debug]] () {} +}; + +void C2::h2 [[gnu::check_thread_safety_debug]] () {} +void C2::C3::h3 [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/check_ts1_test1.h b/External/CheckerGccPlugins/test/check_ts1_test1.h new file mode 100644 index 0000000000000000000000000000000000000000..9261b8c9f20e94e8c949fc143d4fed24933e68b3 --- /dev/null +++ b/External/CheckerGccPlugins/test/check_ts1_test1.h @@ -0,0 +1,3 @@ +#pragma ATLAS check_thread_safety + +void i1 [[gnu::check_thread_safety_debug]] () {} diff --git a/External/CheckerGccPlugins/test/ists1_test.cxx b/External/CheckerGccPlugins/test/ists1_test.cxx deleted file mode 100644 index 6daddb1a02e361478f33c67398496dd396696564..0000000000000000000000000000000000000000 --- a/External/CheckerGccPlugins/test/ists1_test.cxx +++ /dev/null @@ -1,36 +0,0 @@ -#include "ists1_test1.h" -#include "Control/p1/p1/p1a.h" -#include "Control/p1/p1/p1b.h" -#include "Control/p2/p2/p2a.h" -#include "Control/p2/p2/p2b.h" - -void f1 [[gnu::thread_safe_debug]] () {} -void f2 [[gnu::thread_safe_debug]] [[gnu::thread_safe]] () {} - - -struct [[gnu::thread_safe_debug]] C1 -{ - void g1 [[gnu::thread_safe_debug]] () {} - void g2 [[gnu::thread_safe_debug]] (); - void g3(); - void g4 [[gnu::thread_safe]] [[gnu::thread_safe_debug]] (); -}; - - -void C1::g2() {} -void C1::g3 [[gnu::thread_safe_debug]] () {} -void C1::g4() {} - - -struct [[gnu::thread_safe]] C2 -{ - void h1 [[gnu::thread_safe_debug]] () {} - void h2(); - - struct C3 { - void h3(); - }; -}; - -void C2::h2 [[gnu::thread_safe_debug]] () {} -void C2::C3::h3 [[gnu::thread_safe_debug]] () {} diff --git a/External/CheckerGccPlugins/test/ists1_test1.h b/External/CheckerGccPlugins/test/ists1_test1.h deleted file mode 100644 index 15811ed977263ea1cdecc0c61571e14d3ef3a79d..0000000000000000000000000000000000000000 --- a/External/CheckerGccPlugins/test/ists1_test1.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma ATLAS thread_safe - -void i1 [[gnu::thread_safe_debug]] () {} diff --git a/External/CheckerGccPlugins/test/thread1_test.cxx b/External/CheckerGccPlugins/test/thread1_test.cxx index df8d3c76d3531e4dc5bd63530120a8379871b2b2..2cbd2084b6d9ebced36c9c70284f6c52f641cde8 100644 --- a/External/CheckerGccPlugins/test/thread1_test.cxx +++ b/External/CheckerGccPlugins/test/thread1_test.cxx @@ -1,6 +1,6 @@ // testing check_direct_static_use -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety int f1(int xx) @@ -35,6 +35,20 @@ int f4() } +int f5 [[gnu::not_thread_safe]] (int xx) +{ + static int x; + return xx + x; +} + + +int f6 [[gnu::not_reentrant]] (int xx) +{ + static int x; + return xx + x; +} + + struct Y { int y1; diff --git a/External/CheckerGccPlugins/test/thread2_test.cxx b/External/CheckerGccPlugins/test/thread2_test.cxx index 69972ee93c6caf09f7c584e036ad9845aed4f419..ada59181656be55bbd9428f7b4708b84f0f4cfa6 100644 --- a/External/CheckerGccPlugins/test/thread2_test.cxx +++ b/External/CheckerGccPlugins/test/thread2_test.cxx @@ -1,11 +1,13 @@ // testing check_assign_address_of_static -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety static int y1; static const int y2 = 0; //static int y3[10]; +static thread_local int y4; +static int y5 [[gnu::thread_safe]]; int* f1() @@ -63,3 +65,28 @@ struct Y void foo(); }; + +int* f8 [[gnu::not_reentrant]] () +{ + return &y1; +} + + +int* f9() +{ + return &y4; +} + + +int* f10() +{ + return &y5; +} + + +int* f11 [[gnu::not_thread_safe]] () +{ + return &y1; +} + + diff --git a/External/CheckerGccPlugins/test/thread3_test.cxx b/External/CheckerGccPlugins/test/thread3_test.cxx index 536ab14ff67c3672776183330dcc17914618e5aa..b24ce8f12e9bb345afd94757b8124ee33361a9b5 100644 --- a/External/CheckerGccPlugins/test/thread3_test.cxx +++ b/External/CheckerGccPlugins/test/thread3_test.cxx @@ -1,11 +1,12 @@ // testing check_pass_static_by_call. -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety static int y1; static int y2 [[gnu::thread_safe]]; static const int y3 = 10; +static thread_local int y4; void foo1(int, int*); @@ -20,6 +21,7 @@ void f1() foo3(3, &y1); foo3(3, &y2); foo3(3, &y3); + foo3(3, &y4); } @@ -37,3 +39,17 @@ void f2() { c1.foo(); } + + +void f3 [[gnu::not_reentrant]] () +{ + foo1(3, &y1); +} + + +void f4 [[gnu::not_thread_safe]] () +{ + foo1(3, &y1); +} + + diff --git a/External/CheckerGccPlugins/test/thread4_test.cxx b/External/CheckerGccPlugins/test/thread4_test.cxx index caf8e59ba8e4961242fa75e7491efe4619998405..f9348b5bc5fa59a786db11426fd7aa41e02f81fd 100644 --- a/External/CheckerGccPlugins/test/thread4_test.cxx +++ b/External/CheckerGccPlugins/test/thread4_test.cxx @@ -1,6 +1,9 @@ -// testing const_cast check from check_assign_address_of_static +// testing check_discarded_const + +#pragma ATLAS check_thread_safety + +const int* xx(); -#pragma ATLAS thread_safe int* f1(const int* y) { @@ -42,3 +45,47 @@ int* f6(const int* y) return yy; } + +int* f7(const int* y) +{ + const int* yy = y; + const int* yyy = yy; + return const_cast<int*>(yyy); +} + +int* f8 [[gnu::argument_not_const_thread_safe]] (const int* y) +{ + const int* yy = y; + const int* yyy = yy; + return const_cast<int*>(yyy); +} + + +int* f8a [[gnu::not_const_thread_safe]] (const int* y) +{ + const int* yy = y; + const int* yyy = yy; + return const_cast<int*>(yyy); +} + + +int* f9 [[gnu::not_const_thread_safe]] () +{ + const int* y = xx(); + return const_cast<int*>(y); +} + + +int* f9a [[gnu::argument_not_const_thread_safe]] () +{ + const int* y = xx(); + return const_cast<int*>(y); +} + + +int* f10 [[gnu::not_thread_safe]] (const int* y) +{ + return const_cast<int*>(y); +} + + diff --git a/External/CheckerGccPlugins/test/thread5_test.cxx b/External/CheckerGccPlugins/test/thread5_test.cxx index d4ccaa936f00ab5518403e4eb5f75ac43fad762b..b2d38ded51511628fac4af84db6ecdba57cf50a4 100644 --- a/External/CheckerGccPlugins/test/thread5_test.cxx +++ b/External/CheckerGccPlugins/test/thread5_test.cxx @@ -1,7 +1,8 @@ -// testing const_cast check from check_pass_static_by_call +// testing check_discarded_const_in_funcall -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety +const int* xx(); void f1(int* y); void f2(const int* y) { @@ -36,3 +37,31 @@ void f6(const S& s) { const_cast<S&>(s).foo(); } + +void f7 [[gnu::argument_not_const_thread_safe]] (const int* y) +{ + f1(const_cast<int*>(y)); +} + +void f7a [[gnu::not_const_thread_safe]] (const int* y) +{ + f1(const_cast<int*>(y)); +} + +void f8 [[gnu::not_const_thread_safe]] () +{ + const int* y = xx(); + f1(const_cast<int*>(y)); +} + +void f8a [[gnu::argument_not_const_thread_safe]] () +{ + const int* y = xx(); + f1(const_cast<int*>(y)); +} + +void f9 [[gnu::not_thread_safe]] () +{ + const int* y = xx(); + f1(const_cast<int*>(y)); +} diff --git a/External/CheckerGccPlugins/test/thread6_test.cxx b/External/CheckerGccPlugins/test/thread6_test.cxx index fd9af33b5ce513bc4bf2433ea96a17d0ff9fbea7..31f0bbf8846bb630d758194245b42c6d0176f6fd 100644 --- a/External/CheckerGccPlugins/test/thread6_test.cxx +++ b/External/CheckerGccPlugins/test/thread6_test.cxx @@ -1,6 +1,6 @@ // testing mutable checks -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety struct B diff --git a/External/CheckerGccPlugins/test/thread7_test.cxx b/External/CheckerGccPlugins/test/thread7_test.cxx index 740e066ec156112def4f6b2307afc356e6089723..9e546eb54ecb5d44acaa93f5bec50b68b5aa3781 100644 --- a/External/CheckerGccPlugins/test/thread7_test.cxx +++ b/External/CheckerGccPlugins/test/thread7_test.cxx @@ -1,6 +1,6 @@ // testing check for static/mutable members -#pragma ATLAS thread_safe +#pragma ATLAS check_thread_safety struct S diff --git a/External/CheckerGccPlugins/test/thread8_test.cxx b/External/CheckerGccPlugins/test/thread8_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..31f7b09e0656ce74c38ff9ba8f4354c52d9d0501 --- /dev/null +++ b/External/CheckerGccPlugins/test/thread8_test.cxx @@ -0,0 +1,39 @@ +// testing check_discarded_const_from_return + +#pragma ATLAS check_thread_safety + +const int* xx(); + + +int* f1() +{ + return const_cast<int*>(xx()); +} + + +int* f2() +{ + int* y = const_cast<int*>(xx()); + return y; +} + + +int* f3 [[gnu::not_thread_safe]] () +{ + int* y = const_cast<int*>(xx()); + return y; +} + + +int* f4 [[gnu::not_const_thread_safe]] () +{ + int* y = const_cast<int*>(xx()); + return y; +} + + +int* f5 [[gnu::argument_not_const_thread_safe]] () +{ + int* y = const_cast<int*>(xx()); + return y; +} diff --git a/External/CheckerGccPlugins/test/usingns1_test.cxx b/External/CheckerGccPlugins/test/usingns1_test.cxx index ec665a48f7c16b9347d089ec1e5506468b73cfec..399a995ee4f35f175b8d24b9ea75fb826a05c46c 100644 --- a/External/CheckerGccPlugins/test/usingns1_test.cxx +++ b/External/CheckerGccPlugins/test/usingns1_test.cxx @@ -1,4 +1,4 @@ -namespace std { int qq [[gnu::thread_safe]]; } +namespace std { int qq; } using namespace std; using std::qq; #include "usingns1_test.h" diff --git a/External/CheckerGccPlugins/test/usingns1_test.h b/External/CheckerGccPlugins/test/usingns1_test.h index 78c39520c6e0db712bbae7fe58f6ab6ff08cbc58..4b4fdfdd32439fc45bbf04ddffd7e2f55199c906 100755 --- a/External/CheckerGccPlugins/test/usingns1_test.h +++ b/External/CheckerGccPlugins/test/usingns1_test.h @@ -1,7 +1,7 @@ namespace std {} using namespace std; using std::qq; -int xx [[gnu::thread_safe]]; +int xx; namespace foo {} namespace boost { namespace aux { using namespace foo; } } diff --git a/External/CheckerGccPlugins/test/usingns5_test.cxx b/External/CheckerGccPlugins/test/usingns5_test.cxx index 92cec108ee61eef5c70f1a851b17afd7c8ef0229..1cddde899cfa3190e739ef67bc33625da86652e8 100644 --- a/External/CheckerGccPlugins/test/usingns5_test.cxx +++ b/External/CheckerGccPlugins/test/usingns5_test.cxx @@ -17,7 +17,7 @@ public: #include "usingns5_test.h" -const BaseInfoBase* pp [[gnu::thread_safe]] = &BaseInfo<int>::baseinfo(); +const BaseInfoBase* pp = &BaseInfo<int>::baseinfo(); namespace CLHEP {class RandGauss; } using CLHEP::RandGauss; diff --git a/External/CheckerGccPlugins/test/usingns5_test.h b/External/CheckerGccPlugins/test/usingns5_test.h index 3529223793a1aa3d709052596e7a055d25a355fe..339412bf0cb7fa87229b095338ac534c8bf7a6f2 100644 --- a/External/CheckerGccPlugins/test/usingns5_test.h +++ b/External/CheckerGccPlugins/test/usingns5_test.h @@ -7,4 +7,4 @@ const BaseInfoBase& BaseInfo<T>::baseinfo() template <class T> -typename BaseInfo<T>::instance_holder BaseInfo<T>::s_instance [[gnu::thread_safe]]; +typename BaseInfo<T>::instance_holder BaseInfo<T>::s_instance;