Skip to content

Commit 37a184c

Browse files
committed
Added handling of templated arguments and fixed missing ArgLoc
1 parent 7d1c785 commit 37a184c

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ def Cleanup : InheritableAttr {
14231423
let Args = [DeclArgument<Function, "FunctionDecl">];
14241424
let Subjects = SubjectList<[LocalVar]>;
14251425
let Documentation = [CleanupDocs];
1426-
bit IsTypeDependent = 1;
1426+
let IsTypeDependent = 1;
14271427
// FIXME: DeclArgument should be reworked to also store the
14281428
// Expr instead of adding attr specific hacks like the following.
14291429
// See the discussion in https://github.com/llvm/llvm-project/pull/14023.

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8308,10 +8308,13 @@ void Sema::ActOnCleanupAttr(Decl *D, const Attr *A) {
83088308
CleanupAttr *Attr = D->getAttr<CleanupAttr>();
83098309
FunctionDecl *FD = Attr->getFunctionDecl();
83108310
DeclarationNameInfo NI = FD->getNameInfo();
8311+
VarDecl *VD = cast<VarDecl>(D);
8312+
if (VD->getType()->isDependentType())
8313+
return;
83118314

83128315
// We're currently more strict than GCC about what function types we accept.
83138316
// If this ever proves to be a problem it should be easy to fix.
8314-
QualType Ty = this->Context.getPointerType(cast<VarDecl>(D)->getType());
8317+
QualType Ty = this->Context.getPointerType(VD->getType());
83158318
QualType ParamTy = FD->getParamDecl(0)->getType();
83168319
if (!this->IsAssignConvertCompatible(this->CheckAssignmentConstraints(
83178320
FD->getParamDecl(0)->getLocation(), ParamTy, Ty))) {

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,15 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
10071007
continue;
10081008
}
10091009

1010+
if (auto *A = dyn_cast<CleanupAttr>(TmplAttr)) {
1011+
if (!New->hasAttr<CleanupAttr>()) {
1012+
auto *NewAttr = A->clone(Context);
1013+
NewAttr->setArgLoc(A->getArgLoc());
1014+
New->addAttr(NewAttr);
1015+
}
1016+
continue;
1017+
}
1018+
10101019
assert(!TmplAttr->isPackExpansion());
10111020
if (TmplAttr->isLateParsed() && LateAttrs) {
10121021
// Late parsed attributes must be instantiated and attached after the
@@ -1024,8 +1033,10 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
10241033

10251034
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
10261035
*this, TemplateArgs);
1027-
if (NewAttr && isRelevantAttr(*this, New, TmplAttr))
1036+
1037+
if (NewAttr && isRelevantAttr(*this, New, TmplAttr)) {
10281038
New->addAttr(NewAttr);
1039+
}
10291040
}
10301041
}
10311042
}

clang/test/SemaCXX/attr-cleanup.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,27 @@ namespace E {
2727
int v1 __attribute__((cleanup(c3))); // expected-error {{'c3' is not a single function}}
2828
}
2929
}
30+
31+
namespace F {
32+
int open() { return 0; }
33+
void close(decltype(open()) *) {}
34+
35+
void test1() {
36+
auto fd [[gnu::cleanup(close)]] = open();
37+
}
38+
39+
template <typename Ty>
40+
void test2() {
41+
Ty fd [[gnu::cleanup(close)]] = open();
42+
}
43+
44+
template <typename Ty>
45+
void test3() {
46+
Ty fd [[gnu::cleanup(close)]] = open(); // expected-error {{'cleanup' function 'close' parameter has type 'decltype(open()) *' (aka 'int *') which is incompatible with type 'float *'}}
47+
}
48+
49+
int main() {
50+
test2<int>();
51+
test3<float>(); // expected-note {{in instantiation of function template specialization 'F::test3<float>' requested here}}
52+
}
53+
}

0 commit comments

Comments
 (0)