https://github.com/melver updated https://github.com/llvm/llvm-project/pull/123063
>From 6727047d25b8b72f8e23b03a84c0b23f6dad566a Mon Sep 17 00:00:00 2001 From: Marco Elver <el...@google.com> Date: Wed, 15 Jan 2025 13:23:14 +0100 Subject: [PATCH 1/3] Thread Safety Analysis: Support warning on obtaining address of guarded variables Add the optional ability, via `-Wthread-safety-addressof`, to warn when obtaining the address of guarded variables. This is required to avoid false negatives in large C codebases, where data structures are typically implemented through helpers that take pointers to instances of a data structure. We also argue that, while obtaining the address itself does not yet constitute a potential race (in the presence of missing locking), placing the requirement on the pointer-recipient to obtain locks to access the pointed-to data is most likely poor style. This is analogous to passing C++ references to guarded variables, which produces warnings by default. Given that existing codebases using `-Wthread-safety` likely have cases where obtaining the pointer to a guarded variable is benign, the feature is not enabled by default but requires explicit opt-in. --- clang/docs/ReleaseNotes.rst | 3 ++ clang/docs/ThreadSafetyAnalysis.rst | 12 ++++- .../clang/Analysis/Analyses/ThreadSafety.h | 3 ++ clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td | 8 ++++ clang/lib/Analysis/ThreadSafety.cpp | 3 ++ clang/lib/Sema/AnalysisBasedWarnings.cpp | 26 ++++++++--- clang/test/Sema/warn-thread-safety-analysis.c | 11 +++++ .../SemaCXX/warn-thread-safety-analysis.cpp | 44 ++++++++++++++++++- 9 files changed, 102 insertions(+), 9 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 794943b24a003c..abcf0ef236cc2e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -788,6 +788,9 @@ Improvements to Clang's diagnostics require(scope); // Warning! Requires mu1. } +- The :doc:`ThreadSafetyAnalysis` now supports ``-Wthread-safety-addressof``, + which enables warning if the address of guarded variables is obtained. + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index 9c1c32e46989bc..c506844e7c94dc 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -515,8 +515,16 @@ Warning flags + ``-Wthread-safety-analysis``: The core analysis. + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely. This warning can be disabled for code which has a lot of aliases. - + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference. - + + ``-Wthread-safety-reference``: Checks when guarded variables are passed by reference. + +* ``-Wthread-safety-addressof``: Warn when the address of guarded variables is + obtained (``&var``). Since obtaining the address of a variable doesn't + necessarily imply a read or write, the warning is off by default. In + codebases that prefer passing pointers rather than references (for C++ + codebases), or passing pointers is ubiquitous (for C codebases), enabling + this warning will result in fewer false negatives; for example, where the + manipulation of common data structures is done via functions that take + pointers to instances of the data structure. :ref:`negative` are an experimental feature, which are enabled with: diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h index 0fcf5bed1285a4..a61c60cbf531e9 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -54,6 +54,9 @@ enum ProtectedOperationKind { /// Returning a pt-guarded variable by reference. POK_PtReturnByRef, + + /// Obtaining address of a variable (e.g. &x). + POK_AddressOf, }; /// This enum distinguishes between different kinds of lock actions. For diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 594e99a19b64d6..8bd5d043cefa80 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1126,6 +1126,7 @@ def ThreadSafetyReferenceReturn : DiagGroup<"thread-safety-reference-return">; def ThreadSafetyReference : DiagGroup<"thread-safety-reference", [ThreadSafetyReferenceReturn]>; def ThreadSafetyNegative : DiagGroup<"thread-safety-negative">; +def ThreadSafetyAddressof : DiagGroup<"thread-safety-addressof">; def ThreadSafety : DiagGroup<"thread-safety", [ThreadSafetyAttributes, ThreadSafetyAnalysis, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8be4f946dce1cc..8e980dc31e3003 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4140,6 +4140,14 @@ def warn_thread_safety_verbose : Warning<"thread safety verbose warning">, def note_thread_warning_in_fun : Note<"thread warning in function %0">; def note_guarded_by_declared_here : Note<"guarded_by declared here">; +// Thread safety warnings on addressof +def warn_addressof_requires_any_lock : Warning< + "obtaining address of variable %0 requires holding any mutex">, + InGroup<ThreadSafetyAddressof>, DefaultIgnore; +def warn_addressof_requires_lock : Warning< + "obtaining address of variable %1 requires holding %0 '%2'">, + InGroup<ThreadSafetyAddressof>, DefaultIgnore; + // Dummy warning that will trigger "beta" warnings from the analysis if enabled. def warn_thread_safety_beta : Warning<"thread safety beta warning">, InGroup<ThreadSafetyBeta>, DefaultIgnore; diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index bfaf1a0e7c7ffc..3f06b40a623475 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2080,6 +2080,9 @@ void BuildLockset::VisitUnaryOperator(const UnaryOperator *UO) { case UO_PreInc: checkAccess(UO->getSubExpr(), AK_Written); break; + case UO_AddrOf: + checkAccess(UO->getSubExpr(), AK_Read, POK_AddressOf); + break; default: break; } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 589869d0186575..ace36cbecb876f 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1983,11 +1983,21 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, AccessKind AK, SourceLocation Loc) override { - assert((POK == POK_VarAccess || POK == POK_VarDereference) && - "Only works for variables"); - unsigned DiagID = POK == POK_VarAccess? - diag::warn_variable_requires_any_lock: - diag::warn_var_deref_requires_any_lock; + unsigned DiagID = 0; + switch (POK) { + case POK_VarAccess: + DiagID = diag::warn_variable_requires_any_lock; + break; + case POK_VarDereference: + DiagID = diag::warn_var_deref_requires_any_lock; + break; + case POK_AddressOf: + DiagID = diag::warn_addressof_requires_any_lock; + break; + default: + assert(false && "Only works for variables"); + break; + } PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << D << getLockKindFromAccessKind(AK)); Warnings.emplace_back(std::move(Warning), getNotes()); @@ -2006,6 +2016,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { case POK_VarDereference: DiagID = diag::warn_var_deref_requires_lock_precise; break; + case POK_AddressOf: + DiagID = diag::warn_addressof_requires_lock; + break; case POK_FunctionCall: DiagID = diag::warn_fun_requires_lock_precise; break; @@ -2042,6 +2055,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { case POK_VarDereference: DiagID = diag::warn_var_deref_requires_lock; break; + case POK_AddressOf: + DiagID = diag::warn_addressof_requires_lock; + break; case POK_FunctionCall: DiagID = diag::warn_fun_requires_lock; break; diff --git a/clang/test/Sema/warn-thread-safety-analysis.c b/clang/test/Sema/warn-thread-safety-analysis.c index 73b4e4798f6443..cc6af79aadb22b 100644 --- a/clang/test/Sema/warn-thread-safety-analysis.c +++ b/clang/test/Sema/warn-thread-safety-analysis.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta %s // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -fexperimental-late-parse-attributes -DLATE_PARSING %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wthread-safety-addressof -fexperimental-late-parse-attributes -DLATE_PARSING -DCHECK_ADDRESSOF %s #define LOCKABLE __attribute__ ((lockable)) #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) @@ -133,7 +134,12 @@ int main(void) { Foo_func3(5); +#ifdef CHECK_ADDRESSOF + set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}} \ + expected-warning{{obtaining address of variable 'a_' requires holding mutex 'foo_.mu_'}} +#else set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}} +#endif get_value(b_); // expected-warning{{calling function 'get_value' requires holding mutex 'foo_.mu_'}} mutex_exclusive_lock(foo_.mu_); set_value(&a_, 1); @@ -180,6 +186,11 @@ int main(void) { #ifdef LATE_PARSING late_parsing.a_value_defined_before = 1; // expected-warning{{writing variable 'a_value_defined_before' requires holding mutex 'a_mutex_defined_late' exclusively}} late_parsing.a_ptr_defined_before = 0; +# ifdef CHECK_ADDRESSOF + (void)&late_parsing.a_value_defined_before; // expected-warning{{obtaining address of variable 'a_value_defined_before' requires holding mutex 'a_mutex_defined_late'}} +# else + (void)&late_parsing.a_value_defined_before; // no warning +# endif mutex_exclusive_lock(late_parsing.a_mutex_defined_late); mutex_exclusive_lock(late_parsing.a_mutex_defined_early); // expected-warning{{mutex 'a_mutex_defined_early' must be acquired before 'a_mutex_defined_late'}} mutex_exclusive_unlock(late_parsing.a_mutex_defined_early); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 018d6d1bb258b5..ce5c08d32328c2 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -Wthread-safety-addressof -fcxx-exceptions -DUSE_CAPABILITY=1 -DCHECK_ADDRESSOF %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -Wthread-safety-addressof -fcxx-exceptions -DUSE_CAPABILITY=1 -DCHECK_ADDRESSOF %s // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s @@ -4863,6 +4865,11 @@ class Data { int dat; }; +class DataWithAddrOf : public Data { +public: + void* operator&() const; +}; + class DataCell { public: @@ -4900,10 +4907,15 @@ class Foo { a = (*datap2_).getValue(); // \ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} + // Calls operator&, and does not obtain the address. + (void)&data_ao_; // expected-warning {{reading variable 'data_ao_' requires holding mutex 'mu_'}} + (void)__builtin_addressof(data_ao_); // expected-warning {{passing variable 'data_ao_' by reference requires holding mutex 'mu_'}} + mu_.Lock(); data_.setValue(1); datap1_->setValue(1); datap2_->setValue(1); + (void)&data_ao_; mu_.Unlock(); mu_.ReaderLock(); @@ -4911,6 +4923,7 @@ class Foo { datap1_->setValue(0); // reads datap1_, writes *datap1_ a = datap1_->getValue(); a = datap2_->getValue(); + (void)&data_ao_; mu_.Unlock(); } @@ -4939,11 +4952,29 @@ class Foo { data_++; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} --data_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} data_--; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} +#ifdef CHECK_ADDRESSOF + (void)&data_; // expected-warning {{obtaining address of variable 'data_' requires holding mutex 'mu_'}} + (void)&datap1_; // expected-warning {{obtaining address of variable 'datap1_' requires holding mutex 'mu_'}} +#else + (void)&data_; // no warning + (void)&datap1_; // no warning +#endif + (void)(&*datap1_); // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} + (void)&datap2_; // no warning + (void)(&*datap2_); // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} + + mu_.Lock(); + (void)&data_; + mu_.Unlock(); + + mu_.ReaderLock(); + (void)&data_; + mu_.Unlock(); } // const operator tests @@ -4962,6 +4993,7 @@ class Foo { Data data_ GUARDED_BY(mu_); Data* datap1_ GUARDED_BY(mu_); Data* datap2_ PT_GUARDED_BY(mu_); + DataWithAddrOf data_ao_ GUARDED_BY(mu_); }; } // end namespace GuardedNonPrimitiveTypeTest @@ -5870,7 +5902,11 @@ class Foo { } void ptr_test() { - int *b = &a; +#ifdef CHECK_ADDRESSOF + int *b = &a; // expected-warning {{obtaining address of variable 'a' requires holding mutex 'mu'}} +#else + int *b = &a; // no warning +#endif *b = 0; // no expected warning yet } @@ -6089,7 +6125,11 @@ class Return { } Foo *returns_ptr() { - return &foo; // FIXME -- Do we want to warn on this ? +#ifdef CHECK_ADDRESSOF + return &foo; // expected-warning {{obtaining address of variable 'foo' requires holding mutex 'mu'}} +#else + return &foo; // no warning +#endif } Foo &returns_ref2() { >From 9afacb1b097c91a66fcabe09bddb1b2b66686c84 Mon Sep 17 00:00:00 2001 From: Marco Elver <el...@google.com> Date: Tue, 21 Jan 2025 11:13:56 +0100 Subject: [PATCH 2/3] Update documentation wording on false positives and negatives Update documentation wording to be clearer about false positives and negatives of Wthread-safety-addressof. --- clang/docs/ThreadSafetyAnalysis.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index c506844e7c94dc..2d921ac759f84c 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -518,13 +518,15 @@ Warning flags + ``-Wthread-safety-reference``: Checks when guarded variables are passed by reference. * ``-Wthread-safety-addressof``: Warn when the address of guarded variables is - obtained (``&var``). Since obtaining the address of a variable doesn't - necessarily imply a read or write, the warning is off by default. In - codebases that prefer passing pointers rather than references (for C++ - codebases), or passing pointers is ubiquitous (for C codebases), enabling - this warning will result in fewer false negatives; for example, where the - manipulation of common data structures is done via functions that take - pointers to instances of the data structure. + obtained (``&var``). Since obtaining the address of a variable does *not + necessarily imply a read or write*, the warning is off by default to avoid + false positives. In codebases that prefer passing pointers rather than + references (for C++ codebases), or passing pointers is ubiquitous (for C + codebases), enabling this warning will result in fewer false negatives; for + example, where the manipulation of common data structures is done via + functions that take pointers to instances of the data structure. Note, + however, that the analysis does not track pointers, and false positives *and* + negatives are still possible. :ref:`negative` are an experimental feature, which are enabled with: >From 0c4d02e78938e125c84fa673fd6c2b924a3fe81c Mon Sep 17 00:00:00 2001 From: Marco Elver <el...@google.com> Date: Tue, 21 Jan 2025 11:18:00 +0100 Subject: [PATCH 3/3] Change terminology "obtaining address of" -> "taking address of" The wording "take address of" or "taking address of" is more common across the codebase: % git grep 'tak\(e\|ing\) address of' | wc 107 1513 16080 Whereas the wording "obtaining address of" has no occurrence. Use the more common wording. --- clang/docs/ReleaseNotes.rst | 2 +- clang/include/clang/Analysis/Analyses/ThreadSafety.h | 2 +- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++-- clang/test/Sema/warn-thread-safety-analysis.c | 4 ++-- clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index abcf0ef236cc2e..96dfe752bfc0ab 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -789,7 +789,7 @@ Improvements to Clang's diagnostics } - The :doc:`ThreadSafetyAnalysis` now supports ``-Wthread-safety-addressof``, - which enables warning if the address of guarded variables is obtained. + which enables warning on taking the address of guarded variables. Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h index a61c60cbf531e9..c83573171e2110 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -55,7 +55,7 @@ enum ProtectedOperationKind { /// Returning a pt-guarded variable by reference. POK_PtReturnByRef, - /// Obtaining address of a variable (e.g. &x). + /// Taking address of a variable (e.g. &x). POK_AddressOf, }; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8e980dc31e3003..b7fa2d2c6f1315 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4142,10 +4142,10 @@ def note_guarded_by_declared_here : Note<"guarded_by declared here">; // Thread safety warnings on addressof def warn_addressof_requires_any_lock : Warning< - "obtaining address of variable %0 requires holding any mutex">, + "taking address of variable %0 requires holding any mutex">, InGroup<ThreadSafetyAddressof>, DefaultIgnore; def warn_addressof_requires_lock : Warning< - "obtaining address of variable %1 requires holding %0 '%2'">, + "taking address of variable %1 requires holding %0 '%2'">, InGroup<ThreadSafetyAddressof>, DefaultIgnore; // Dummy warning that will trigger "beta" warnings from the analysis if enabled. diff --git a/clang/test/Sema/warn-thread-safety-analysis.c b/clang/test/Sema/warn-thread-safety-analysis.c index cc6af79aadb22b..87005db1d3f20f 100644 --- a/clang/test/Sema/warn-thread-safety-analysis.c +++ b/clang/test/Sema/warn-thread-safety-analysis.c @@ -136,7 +136,7 @@ int main(void) { #ifdef CHECK_ADDRESSOF set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}} \ - expected-warning{{obtaining address of variable 'a_' requires holding mutex 'foo_.mu_'}} + expected-warning{{taking address of variable 'a_' requires holding mutex 'foo_.mu_'}} #else set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}} #endif @@ -187,7 +187,7 @@ int main(void) { late_parsing.a_value_defined_before = 1; // expected-warning{{writing variable 'a_value_defined_before' requires holding mutex 'a_mutex_defined_late' exclusively}} late_parsing.a_ptr_defined_before = 0; # ifdef CHECK_ADDRESSOF - (void)&late_parsing.a_value_defined_before; // expected-warning{{obtaining address of variable 'a_value_defined_before' requires holding mutex 'a_mutex_defined_late'}} + (void)&late_parsing.a_value_defined_before; // expected-warning{{taking address of variable 'a_value_defined_before' requires holding mutex 'a_mutex_defined_late'}} # else (void)&late_parsing.a_value_defined_before; // no warning # endif diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index ce5c08d32328c2..60633312700b93 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -4953,8 +4953,8 @@ class Foo { --data_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} data_--; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} #ifdef CHECK_ADDRESSOF - (void)&data_; // expected-warning {{obtaining address of variable 'data_' requires holding mutex 'mu_'}} - (void)&datap1_; // expected-warning {{obtaining address of variable 'datap1_' requires holding mutex 'mu_'}} + (void)&data_; // expected-warning {{taking address of variable 'data_' requires holding mutex 'mu_'}} + (void)&datap1_; // expected-warning {{taking address of variable 'datap1_' requires holding mutex 'mu_'}} #else (void)&data_; // no warning (void)&datap1_; // no warning @@ -5903,7 +5903,7 @@ class Foo { void ptr_test() { #ifdef CHECK_ADDRESSOF - int *b = &a; // expected-warning {{obtaining address of variable 'a' requires holding mutex 'mu'}} + int *b = &a; // expected-warning {{taking address of variable 'a' requires holding mutex 'mu'}} #else int *b = &a; // no warning #endif @@ -6126,7 +6126,7 @@ class Return { Foo *returns_ptr() { #ifdef CHECK_ADDRESSOF - return &foo; // expected-warning {{obtaining address of variable 'foo' requires holding mutex 'mu'}} + return &foo; // expected-warning {{taking address of variable 'foo' requires holding mutex 'mu'}} #else return &foo; // no warning #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits