Thanks! On Fri, Aug 11, 2017 at 4:56 PM Josh Gao <jm...@google.com> wrote:
> Reverted in r310698. > > On Fri, Aug 11, 2017 at 12:51 AM, Josh Gao <jm...@google.com> wrote: > >> Sorry for the breakage, I'm reverting the patch that caused this now. >> >> On Fri, Aug 11, 2017 at 12:36 AM, NAKAMURA Takumi <geek4ci...@gmail.com> >> wrote: >> >>> It causes failure in check-libcxx with just-built clang. >>> >>> >>> http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/758 >>> >>> >>> On Wed, Aug 9, 2017 at 4:45 AM Josh Gao via cfe-commits < >>> cfe-commits@lists.llvm.org> wrote: >>> >>>> Author: jmgao >>>> Date: Tue Aug 8 12:44:35 2017 >>>> New Revision: 310403 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=310403&view=rev >>>> Log: >>>> Thread Safety Analysis: warn on nonsensical attributes. >>>> >>>> Add warnings in cases where an implicit `this` argument is expected to >>>> attributes because either `this` doesn't exist because the attribute is >>>> on a free function, or because `this` is on a type that doesn't have a >>>> corresponding capability/lockable/scoped_lockable attribute. >>>> >>>> Reviewers: delesley, aaron.ballman >>>> >>>> Differential Revision: https://reviews.llvm.org/D36237 >>>> >>>> Modified: >>>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >>>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> cfe/trunk/test/Sema/attr-capabilities.c >>>> cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp >>>> >>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=310403&r1=310402&r2=310403&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 8 >>>> 12:44:35 2017 >>>> @@ -2932,6 +2932,16 @@ def warn_thread_attribute_decl_not_locka >>>> "%0 attribute can only be applied in a context annotated " >>>> "with 'capability(\"mutex\")' attribute">, >>>> InGroup<ThreadSafetyAttributes>, DefaultIgnore; >>>> +def warn_thread_attribute_noargs_not_lockable : Warning< >>>> + "%0 attribute requires type annotated with 'capability' attribute; " >>>> + "type here is %1">, >>>> + InGroup<ThreadSafetyAttributes>, DefaultIgnore; >>>> +def warn_thread_attribute_noargs_not_method : Warning< >>>> + "%0 attribute without arguments can only be applied to a method of a >>>> class">, >>>> + InGroup<ThreadSafetyAttributes>, DefaultIgnore; >>>> +def warn_thread_attribute_noargs_static_method : Warning< >>>> + "%0 attribute without arguments cannot be applied to a static >>>> method">, >>>> + InGroup<ThreadSafetyAttributes>, DefaultIgnore; >>>> def warn_thread_attribute_decl_not_pointer : Warning< >>>> "%0 only applies to pointer types; type here is %1">, >>>> InGroup<ThreadSafetyAttributes>, DefaultIgnore; >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=310403&r1=310402&r2=310403&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Aug 8 12:44:35 2017 >>>> @@ -480,7 +480,7 @@ static const RecordType *getRecordType(Q >>>> return nullptr; >>>> } >>>> >>>> -static bool checkRecordTypeForCapability(Sema &S, QualType Ty) { >>>> +template <typename T> static bool checkRecordTypeForAttr(Sema &S, >>>> QualType Ty) { >>>> const RecordType *RT = getRecordType(Ty); >>>> >>>> if (!RT) >>>> @@ -497,7 +497,7 @@ static bool checkRecordTypeForCapability >>>> >>>> // Check if the record itself has a capability. >>>> RecordDecl *RD = RT->getDecl(); >>>> - if (RD->hasAttr<CapabilityAttr>()) >>>> + if (RD->hasAttr<T>()) >>>> return true; >>>> >>>> // Else check if any base classes have a capability. >>>> @@ -505,14 +505,14 @@ static bool checkRecordTypeForCapability >>>> CXXBasePaths BPaths(false, false); >>>> if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath >>>> &) { >>>> const auto *Type = BS->getType()->getAs<RecordType>(); >>>> - return Type->getDecl()->hasAttr<CapabilityAttr>(); >>>> + return Type->getDecl()->hasAttr<T>(); >>>> }, BPaths)) >>>> return true; >>>> } >>>> return false; >>>> } >>>> >>>> -static bool checkTypedefTypeForCapability(QualType Ty) { >>>> +template <typename T> static bool checkTypedefTypeForAttr(QualType Ty) >>>> { >>>> const auto *TD = Ty->getAs<TypedefType>(); >>>> if (!TD) >>>> return false; >>>> @@ -521,19 +521,27 @@ static bool checkTypedefTypeForCapabilit >>>> if (!TN) >>>> return false; >>>> >>>> - return TN->hasAttr<CapabilityAttr>(); >>>> + return TN->hasAttr<T>(); >>>> } >>>> >>>> -static bool typeHasCapability(Sema &S, QualType Ty) { >>>> - if (checkTypedefTypeForCapability(Ty)) >>>> +template <typename T> static bool typeHasAttr(Sema &S, QualType Ty) { >>>> + if (checkTypedefTypeForAttr<T>(Ty)) >>>> return true; >>>> >>>> - if (checkRecordTypeForCapability(S, Ty)) >>>> + if (checkRecordTypeForAttr<T>(S, Ty)) >>>> return true; >>>> >>>> return false; >>>> } >>>> >>>> +static bool typeHasCapability(Sema &S, QualType Ty) { >>>> + return typeHasAttr<CapabilityAttr>(S, Ty); >>>> +} >>>> + >>>> +static bool typeHasScopedLockable(Sema &S, QualType Ty) { >>>> + return typeHasAttr<ScopedLockableAttr>(S, Ty); >>>> +} >>>> + >>>> static bool isCapabilityExpr(Sema &S, const Expr *Ex) { >>>> // Capability expressions are simple expressions involving the >>>> boolean logic >>>> // operators &&, || or !, a simple DeclRefExpr, CastExpr or a >>>> ParenExpr. Once >>>> @@ -570,6 +578,8 @@ static void checkAttrArgsAreCapabilityOb >>>> SmallVectorImpl<Expr *> >>>> &Args, >>>> int Sidx = 0, >>>> bool ParamIdxOk = false) { >>>> + bool TriedParam = false; >>>> + >>>> for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { >>>> Expr *ArgExp = Attr.getArgAsExpr(Idx); >>>> >>>> @@ -610,15 +620,18 @@ static void checkAttrArgsAreCapabilityOb >>>> const RecordType *RT = getRecordType(ArgTy); >>>> >>>> // Now check if we index into a record type function param. >>>> - if(!RT && ParamIdxOk) { >>>> + if (!RT && ParamIdxOk) { >>>> FunctionDecl *FD = dyn_cast<FunctionDecl>(D); >>>> IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); >>>> - if(FD && IL) { >>>> + if (FD && IL) { >>>> + // Don't emit free function warnings if an index was given. >>>> + TriedParam = true; >>>> + >>>> unsigned int NumParams = FD->getNumParams(); >>>> llvm::APInt ArgValue = IL->getValue(); >>>> uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); >>>> uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; >>>> - if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > >>>> NumParams) { >>>> + if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > >>>> NumParams) { >>>> S.Diag(Attr.getLoc(), >>>> diag::err_attribute_argument_out_of_range) >>>> << Attr.getName() << Idx + 1 << NumParams; >>>> continue; >>>> @@ -637,6 +650,28 @@ static void checkAttrArgsAreCapabilityOb >>>> >>>> Args.push_back(ArgExp); >>>> } >>>> + >>>> + // If we don't have any lockable arguments, verify that we're an >>>> instance >>>> + // method on a lockable type. >>>> + if (Args.empty() && !TriedParam) { >>>> + if (auto *MD = dyn_cast<CXXMethodDecl>(D)) { >>>> + if (MD->isStatic()) { >>>> + S.Diag(Attr.getLoc(), >>>> diag::warn_thread_attribute_noargs_static_method) >>>> + << Attr.getName(); >>>> + return; >>>> + } >>>> + >>>> + QualType ThisType = MD->getThisType(MD->getASTContext()); >>>> + if (!typeHasCapability(S, ThisType) && >>>> + !typeHasScopedLockable(S, ThisType)) { >>>> + S.Diag(Attr.getLoc(), >>>> diag::warn_thread_attribute_noargs_not_lockable) >>>> + << Attr.getName() << ThisType; >>>> + } >>>> + } else { >>>> + S.Diag(Attr.getLoc(), >>>> diag::warn_thread_attribute_noargs_not_method) >>>> + << Attr.getName(); >>>> + } >>>> + } >>>> } >>>> >>>> >>>> >>>> //===----------------------------------------------------------------------===// >>>> >>>> Modified: cfe/trunk/test/Sema/attr-capabilities.c >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-capabilities.c?rev=310403&r1=310402&r2=310403&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/Sema/attr-capabilities.c (original) >>>> +++ cfe/trunk/test/Sema/attr-capabilities.c Tue Aug 8 12:44:35 2017 >>>> @@ -37,15 +37,25 @@ void Func6(void) __attribute__((requires >>>> void Func7(void) __attribute__((assert_capability(GUI))) {} >>>> void Func8(void) __attribute__((assert_shared_capability(GUI))) {} >>>> >>>> +void Func9(void) __attribute__((assert_capability())) {} // >>>> expected-warning {{'assert_capability' attribute without arguments can only >>>> be applied to a method of a class}} >>>> +void Func10(void) __attribute__((assert_shared_capability())) {} // >>>> expected-warning {{'assert_shared_capability' attribute without arguments >>>> can only be applied to a method of a class}} >>>> + >>>> void Func11(void) __attribute__((acquire_capability(GUI))) {} >>>> void Func12(void) __attribute__((acquire_shared_capability(GUI))) {} >>>> >>>> +void Func13(void) __attribute__((acquire_capability())) {} // >>>> expected-warning {{'acquire_capability' attribute without arguments can >>>> only be applied to a method of a class}} >>>> +void Func14(void) __attribute__((acquire_shared_capability())) {} // >>>> expected-warning {{'acquire_shared_capability' attribute without arguments >>>> can only be applied to a method of a class}} >>>> + >>>> void Func15(void) __attribute__((release_capability(GUI))) {} >>>> void Func16(void) __attribute__((release_shared_capability(GUI))) {} >>>> void Func17(void) __attribute__((release_generic_capability(GUI))) {} >>>> >>>> -void Func21(void) __attribute__((try_acquire_capability(1))) {} >>>> -void Func22(void) __attribute__((try_acquire_shared_capability(1))) {} >>>> +void Func18(void) __attribute__((release_capability())) {} // >>>> expected-warning {{'release_capability' attribute without arguments can >>>> only be applied to a method of a class}} >>>> +void Func19(void) __attribute__((release_shared_capability())) {} // >>>> expected-warning {{'release_shared_capability' attribute without arguments >>>> can only be applied to a method of a class}} >>>> +void Func20(void) __attribute__((release_generic_capability())) {} // >>>> expected-warning {{'release_generic_capability' attribute without arguments >>>> can only be applied to a method of a class}} >>>> + >>>> +void Func21(void) __attribute__((try_acquire_capability(1))) {} // >>>> expected-warning {{'try_acquire_capability' attribute without arguments can >>>> only be applied to a method of a class}} >>>> +void Func22(void) __attribute__((try_acquire_shared_capability(1))) {} >>>> // expected-warning {{'try_acquire_shared_capability' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> void Func23(void) __attribute__((try_acquire_capability(1, GUI))) {} >>>> void Func24(void) __attribute__((try_acquire_shared_capability(1, >>>> GUI))) {} >>>> >>>> Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp?rev=310403&r1=310402&r2=310403&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original) >>>> +++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Tue Aug 8 >>>> 12:44:35 2017 >>>> @@ -571,11 +571,11 @@ UnlockableMu ab_var_arg_bad_5 ACQUIRED_B >>>> >>>> // takes zero or more arguments, all locks (vars/fields) >>>> >>>> -void elf_function() EXCLUSIVE_LOCK_FUNCTION(); >>>> +void elf_function() EXCLUSIVE_LOCK_FUNCTION(); // expected-warning >>>> {{'exclusive_lock_function' attribute without arguments can only be applied >>>> to a method of a class}} >>>> >>>> void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2); >>>> >>>> -int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION(); >>>> +int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION(); // expected-warning >>>> {{'exclusive_lock_function' attribute without arguments can only be applied >>>> to a method of a class}} >>>> >>>> int elf_testfn(int y) { >>>> int x EXCLUSIVE_LOCK_FUNCTION() = y; // \ >>>> @@ -590,7 +590,7 @@ class ElfFoo { >>>> private: >>>> int test_field EXCLUSIVE_LOCK_FUNCTION(); // \ >>>> // expected-warning {{'exclusive_lock_function' attribute only >>>> applies to functions}} >>>> - void test_method() EXCLUSIVE_LOCK_FUNCTION(); >>>> + void test_method() EXCLUSIVE_LOCK_FUNCTION(); // expected-warning >>>> {{'exclusive_lock_function' attribute requires type annotated with >>>> 'capability' attribute; type here is 'ElfFoo *'}} >>>> }; >>>> >>>> class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \ >>>> @@ -643,11 +643,11 @@ int elf_function_bad_7() EXCLUSIVE_LOCK_ >>>> >>>> // takes zero or more arguments, all locks (vars/fields) >>>> >>>> -void slf_function() SHARED_LOCK_FUNCTION(); >>>> +void slf_function() SHARED_LOCK_FUNCTION(); // expected-warning >>>> {{'shared_lock_function' attribute without arguments can only be applied to >>>> a method of a class}} >>>> >>>> void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2); >>>> >>>> -int slf_testfn(int y) SHARED_LOCK_FUNCTION(); >>>> +int slf_testfn(int y) SHARED_LOCK_FUNCTION(); // expected-warning >>>> {{'shared_lock_function' attribute without arguments can only be applied to >>>> a method of a class}} >>>> >>>> int slf_testfn(int y) { >>>> int x SHARED_LOCK_FUNCTION() = y; // \ >>>> @@ -665,7 +665,8 @@ class SlfFoo { >>>> private: >>>> int test_field SHARED_LOCK_FUNCTION(); // \ >>>> // expected-warning {{'shared_lock_function' attribute only >>>> applies to functions}} >>>> - void test_method() SHARED_LOCK_FUNCTION(); >>>> + void test_method() SHARED_LOCK_FUNCTION(); // \ >>>> + // expected-warning {{'shared_lock_function' attribute requires >>>> type annotated with 'capability' attribute; type here is 'SlfFoo *'}} >>>> }; >>>> >>>> class SHARED_LOCK_FUNCTION() SlfTestClass { // \ >>>> @@ -716,14 +717,16 @@ int slf_function_bad_7() SHARED_LOCK_FUN >>>> // takes a mandatory boolean or integer argument specifying the retval >>>> // plus an optional list of locks (vars/fields) >>>> >>>> -void etf_function() __attribute__((exclusive_trylock_function)); // \ >>>> - // expected-error {{'exclusive_trylock_function' attribute takes at >>>> least 1 argument}} >>>> +void etf_function() __attribute__((exclusive_trylock_function)); // \ >>>> + // expected-error {{'exclusive_trylock_function' attribute takes at >>>> least 1 argument}} \ >>>> >>>> void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2); >>>> >>>> -void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1); >>>> +void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'exclusive_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> -int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1); >>>> +int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'exclusive_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> int etf_testfn(int y) { >>>> int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \ >>>> @@ -732,13 +735,14 @@ int etf_testfn(int y) { >>>> }; >>>> >>>> int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ >>>> - // expected-warning {{'exclusive_trylock_function' attribute only >>>> applies to functions}} >>>> + // expected-warning {{'exclusive_trylock_function' attribute only >>>> applies to functions}} \ >>>> >>>> class EtfFoo { >>>> private: >>>> int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ >>>> // expected-warning {{'exclusive_trylock_function' attribute only >>>> applies to functions}} >>>> - void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1); >>>> + void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'exclusive_trylock_function' attribute >>>> requires type annotated with 'capability' attribute; type here is 'EtfFoo >>>> *'}} >>>> }; >>>> >>>> class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \ >>>> @@ -759,7 +763,8 @@ int etf_function_5() EXCLUSIVE_TRYLOCK_F >>>> int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef); >>>> int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, >>>> muDoubleWrapper.getWrapper()->getMu()); >>>> int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer); >>>> -int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true); >>>> +int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true); // \ >>>> + // expected-warning {{'exclusive_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> >>>> // illegal attribute arguments >>>> @@ -794,9 +799,11 @@ void stf_function() __attribute__((share >>>> >>>> void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2); >>>> >>>> -void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1); >>>> +void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'shared_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> -int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1); >>>> +int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'shared_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> int stf_testfn(int y) { >>>> int x SHARED_TRYLOCK_FUNCTION(1) = y; // \ >>>> @@ -815,7 +822,8 @@ class StfFoo { >>>> private: >>>> int test_field SHARED_TRYLOCK_FUNCTION(1); // \ >>>> // expected-warning {{'shared_trylock_function' attribute only >>>> applies to functions}} >>>> - void test_method() SHARED_TRYLOCK_FUNCTION(1); >>>> + void test_method() SHARED_TRYLOCK_FUNCTION(1); // \ >>>> + // expected-warning {{'shared_trylock_function' attribute requires >>>> type annotated with 'capability' attribute; type here is 'StfFoo *'}} >>>> }; >>>> >>>> class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \ >>>> @@ -833,7 +841,8 @@ int stf_function_5() SHARED_TRYLOCK_FUNC >>>> int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef); >>>> int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, >>>> muDoubleWrapper.getWrapper()->getMu()); >>>> int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer); >>>> -int stf_function_9() SHARED_TRYLOCK_FUNCTION(true); >>>> +int stf_function_9() SHARED_TRYLOCK_FUNCTION(true); // \ >>>> + // expected-warning {{'shared_trylock_function' attribute without >>>> arguments can only be applied to a method of a class}} >>>> >>>> >>>> // illegal attribute arguments >>>> @@ -862,11 +871,14 @@ int stf_function_bad_6() SHARED_TRYLOCK_ >>>> >>>> // takes zero or more arguments, all locks (vars/fields) >>>> >>>> -void uf_function() UNLOCK_FUNCTION(); >>>> +void uf_function() UNLOCK_FUNCTION(); // \ >>>> + // expected-warning {{'unlock_function' attribute without arguments >>>> can only be applied to a method of a class}} >>>> + >>>> >>>> void uf_function_args() UNLOCK_FUNCTION(mu1, mu2); >>>> >>>> -int uf_testfn(int y) UNLOCK_FUNCTION(); >>>> +int uf_testfn(int y) UNLOCK_FUNCTION(); //\ >>>> + // expected-warning {{'unlock_function' attribute without arguments >>>> can only be applied to a method of a class}} >>>> >>>> int uf_testfn(int y) { >>>> int x UNLOCK_FUNCTION() = y; // \ >>>> @@ -881,7 +893,8 @@ class UfFoo { >>>> private: >>>> int test_field UNLOCK_FUNCTION(); // \ >>>> // expected-warning {{'unlock_function' attribute only applies to >>>> functions}} >>>> - void test_method() UNLOCK_FUNCTION(); >>>> + void test_method() UNLOCK_FUNCTION(); // \ >>>> + // expected-warning {{'unlock_function' attribute requires type >>>> annotated with 'capability' attribute; type here is 'UfFoo *'}} >>>> }; >>>> >>>> class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \ >>>> @@ -1524,4 +1537,4 @@ namespace CRASH_POST_R301735 { >>>> Mutex mu_; >>>> }; >>>> } >>>> -#endif >>>> \ No newline at end of file >>>> +#endif >>>> >>>> >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> cfe-commits@lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>> >>> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits