HomePhabricator

Correct class-template deprecation behavior

Description

Correct class-template deprecation behavior

Based on the comment in the test, and my reading of the standard, a deprecated warning should be issued in the following case:
template<typename T> [[deprecated]] class Foo{}; Foo<int> f;

This was not the case, because the ClassTemplateSpecializationDecl creation did not also copy the deprecated attribute.

Note: I did NOT audit the complete set of attributes to see WHICH ones should be copied, so instead I simply copy ONLY the deprecated attribute.

Differential Revision: https://reviews.llvm.org/D27486

Details

Committed
erichkeaneMar 21 2017, 10:49 AM
Differential Revision
D27486: Correct class-template deprecation behavior
Parents
rL298409: Create instance of DynamicLoaderPOSIXDYLD on NetBSD
Branches
Unknown
Tags
Unknown

Event Timeline

mboehme added a subscriber: mboehme.EditedMar 22 2017, 6:32 AM

This doesn't correctly propagate attributes on declarations that have more than one attribute of the same kind (repro below).

It seems the fix may simply be to delete the "&& !DeclContainsAttr(New, NewAttr->getKind()" in InstantiateAttrsForDecl(), but I'm not sure enough that this is the correct fix, so I'll revert this for the time being (and r298433, which is a follow-on from this change).

The following code should compile without warnings:

class Mutex {
public:
  void Lock() __attribute__((exclusive_lock_function()));
  void Unlock() __attribute__((unlock_function()));
};

class A {
public:
  Mutex mu1, mu2;

  void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {}

  template <class T> void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {
    foo();
  }
};

void f() {
  A a;
  a.mu1.Lock();
  a.mu2.Lock();
  a.bar<int>();
  a.mu2.Unlock();
  a.mu1.Unlock();
}

Trying to compile this with "clang++ -std=c++11 -fsyntax-only -Wthread-safety-analysis -Werror", I get

thread_safety.cc:14:5: error: 
      calling function 'foo' requires holding mutex 'mu2' exclusively
      [-Werror,-Wthread-safety-analysis]
    foo();
    ^
thread_safety.cc:22:5: note: 
      in instantiation of function template specialization 'A::bar<int>'
      requested here
  a.bar<int>();
    ^
1 error generated.

Note: The error goes away if I make bar() a non-template function.

Thanks for the reproducer. I'll add that as a test and see if I can update the patch.