diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 6 | ||||
| -rw-r--r-- | clang/lib/AST/DeclBase.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Frontend/PCHWriterDecl.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-function-2.cpp | 11 | 
8 files changed, 35 insertions, 17 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index f6478d9ea66..fe091ad17bc 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -330,7 +330,11 @@ public:    /// \brief Whether this declaration was used, meaning that a definition    /// is required. -  bool isUsed() const; +  /// +  /// \param CheckUsedAttr When true, also consider the "used" attribute +  /// (in addition to the "used" bit set by \c setUsed()) when determining +  /// whether the function is used. +  bool isUsed(bool CheckUsedAttr = true) const;    void setUsed(bool U = true) { Used = U; } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index f1b78e40fc8..104df7ae84f 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -212,17 +212,17 @@ ASTContext &Decl::getASTContext() const {    return getTranslationUnitDecl()->getASTContext();  } -bool Decl::isUsed() const {  +bool Decl::isUsed(bool CheckUsedAttr) const {     if (Used)      return true;    // Check for used attribute. -  if (hasAttr<UsedAttr>()) +  if (CheckUsedAttr && hasAttr<UsedAttr>())      return true;    // Check redeclarations for used attribute.    for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { -    if (I->hasAttr<UsedAttr>() || I->Used) +    if ((CheckUsedAttr && I->hasAttr<UsedAttr>()) || I->Used)        return true;    } diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 6b88dfcae41..36ce5c047fe 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/lib/Frontend/PCHWriterDecl.cpp @@ -118,7 +118,7 @@ void PCHDeclWriter::VisitDecl(Decl *D) {    Record.push_back(D->isInvalidDecl());    Record.push_back(D->hasAttrs());    Record.push_back(D->isImplicit()); -  Record.push_back(D->isUsed()); +  Record.push_back(D->isUsed(false));    Record.push_back(D->getAccess());    Record.push_back(D->getPCHLevel());  } @@ -443,7 +443,7 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {    if (!D->getTypeSourceInfo() &&        !D->hasAttrs() &&        !D->isImplicit() && -      !D->isUsed() && +      !D->isUsed(false) &&        D->getAccess() == AS_none &&        D->getPCHLevel() == 0 &&        D->getStorageClass() == 0 && diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 8bdf971d965..eadc2ad253d 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -226,7 +226,8 @@ void Sema::ActOnEndOfTranslationUnit() {    // Remove functions that turned out to be used.    UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(),                                            UnusedStaticFuncs.end(),  -                                         std::mem_fun(&FunctionDecl::isUsed)),  +                             std::bind2nd(std::mem_fun(&FunctionDecl::isUsed), +                                          true)),                             UnusedStaticFuncs.end());    // Check for #pragma weak identifiers that were never declared diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2a881ff4348..c6f149e8fed 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4216,7 +4216,7 @@ namespace {  void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,                                              CXXConstructorDecl *Constructor) {    assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() && -          !Constructor->isUsed()) && +          !Constructor->isUsed(false)) &&      "DefineImplicitDefaultConstructor - call it for implicit default ctor");    CXXRecordDecl *ClassDecl = Constructor->getParent(); @@ -4237,7 +4237,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,  void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,                                      CXXDestructorDecl *Destructor) { -  assert((Destructor->isImplicit() && !Destructor->isUsed()) && +  assert((Destructor->isImplicit() && !Destructor->isUsed(false)) &&           "DefineImplicitDestructor - call it for implicit default dtor");    CXXRecordDecl *ClassDecl = Destructor->getParent();    assert(ClassDecl && "DefineImplicitDestructor - invalid destructor"); @@ -4466,7 +4466,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,    assert((CopyAssignOperator->isImplicit() &&             CopyAssignOperator->isOverloadedOperator() &&            CopyAssignOperator->getOverloadedOperator() == OO_Equal && -          !CopyAssignOperator->isUsed()) && +          !CopyAssignOperator->isUsed(false)) &&           "DefineImplicitCopyAssignment called for wrong function");    CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent(); @@ -4766,7 +4766,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,                                     unsigned TypeQuals) {    assert((CopyConstructor->isImplicit() &&            CopyConstructor->isCopyConstructor(TypeQuals) && -          !CopyConstructor->isUsed()) && +          !CopyConstructor->isUsed(false)) &&           "DefineImplicitCopyConstructor - call it for implicit copy ctor");    CXXRecordDecl *ClassDecl = CopyConstructor->getParent(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fa403c78d06..5882381e222 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7500,7 +7500,7 @@ Sema::PopExpressionEvaluationContext() {  void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {    assert(D && "No declaration?"); -  if (D->isUsed()) +  if (D->isUsed(false))      return;    // Mark a parameter or variable declaration "used", regardless of whether we're in a @@ -7543,24 +7543,24 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {      unsigned TypeQuals;      if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) { -        if (!Constructor->isUsed()) +        if (!Constructor->isUsed(false))            DefineImplicitDefaultConstructor(Loc, Constructor);      } else if (Constructor->isImplicit() &&                 Constructor->isCopyConstructor(TypeQuals)) { -      if (!Constructor->isUsed()) +      if (!Constructor->isUsed(false))          DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);      }      MarkVTableUsed(Loc, Constructor->getParent());    } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { -    if (Destructor->isImplicit() && !Destructor->isUsed()) +    if (Destructor->isImplicit() && !Destructor->isUsed(false))        DefineImplicitDestructor(Loc, Destructor);      if (Destructor->isVirtual())        MarkVTableUsed(Loc, Destructor->getParent());    } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {      if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&          MethodDecl->getOverloadedOperator() == OO_Equal) { -      if (!MethodDecl->isUsed()) +      if (!MethodDecl->isUsed(false))          DefineImplicitCopyAssignment(Loc, MethodDecl);      } else if (MethodDecl->isVirtual())        MarkVTableUsed(Loc, MethodDecl->getParent()); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index b7059e57523..1b28579e61d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -361,7 +361,9 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {      Var->setLexicalDeclContext(D->getLexicalDeclContext());    Var->setAccess(D->getAccess()); -  Var->setUsed(D->isUsed()); +   +  if (!D->isStaticDataMember()) +    Var->setUsed(D->isUsed(false));    // FIXME: In theory, we could have a previous declaration for variables that    // are not static data members. diff --git a/clang/test/SemaTemplate/instantiate-function-2.cpp b/clang/test/SemaTemplate/instantiate-function-2.cpp index afca3587844..ebc0ef3a9f9 100644 --- a/clang/test/SemaTemplate/instantiate-function-2.cpp +++ b/clang/test/SemaTemplate/instantiate-function-2.cpp @@ -20,3 +20,14 @@ namespace PR7184 {    template void f<int>();  } + +namespace UsedAttr { +  template<typename T> +  void __attribute__((used)) foo() { +    T *x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} +  } + +  void bar() { +    foo<int>(); // expected-note{{instantiation of}} +  } +}  | 

