Skip to content

Commit 543e5f5

Browse files
authored
Fix crash with align_value diagnostic reporting (#135013)
We were passing the address of a local variable to a call to Diag() which then tried to use the object after its lifetime ended, resulting in crashes. We no longer pass the temporary object any longer. Fixes #26612
1 parent 751c3f5 commit 543e5f5

File tree

6 files changed

+54
-20
lines changed

6 files changed

+54
-20
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ Bug Fixes to Attribute Support
386386
or too few attribute argument indicies for the specified callback function.
387387
(#GH47451)
388388

389+
- No longer crashing on ``__attribute__((align_value(N)))`` during template
390+
instantiation when the function parameter type is not a pointer or reference.
391+
(#GH26612)
392+
389393
Bug Fixes to C++ Support
390394
^^^^^^^^^^^^^^^^^^^^^^^^
391395

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4510,7 +4510,7 @@ class Sema final : public SemaBase {
45104510
getAttrLoc(const AttrInfo &AL) {
45114511
return AL.getLocation();
45124512
}
4513-
SourceLocation getAttrLoc(const ParsedAttr &AL);
4513+
SourceLocation getAttrLoc(const AttributeCommonInfo &CI);
45144514

45154515
/// If Expr is a valid integer constant, get the value of the integer
45164516
/// expression and return success or failure. May output an error.

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
8686
return AL.getNumArgs() + AL.hasParsedType();
8787
}
8888

89-
SourceLocation Sema::getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
89+
SourceLocation Sema::getAttrLoc(const AttributeCommonInfo &CI) {
90+
return CI.getLoc();
91+
}
9092

9193
/// Wrapper around checkUInt32Argument, with an extra check to be sure
9294
/// that the result will fit into a regular (signed) int. All args have the same
@@ -1415,13 +1417,11 @@ void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
14151417
Expr *OE) {
14161418
QualType ResultType = getFunctionOrMethodResultType(D);
14171419
SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1418-
1419-
AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1420-
SourceLocation AttrLoc = TmpAttr.getLocation();
1420+
SourceLocation AttrLoc = CI.getLoc();
14211421

14221422
if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
14231423
Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1424-
<< &TmpAttr << TmpAttr.getRange() << SR;
1424+
<< CI << CI.getRange() << SR;
14251425
return;
14261426
}
14271427

@@ -1430,12 +1430,10 @@ void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
14301430
if (!(I = E->getIntegerConstantExpr(Context))) {
14311431
if (OE)
14321432
Diag(AttrLoc, diag::err_attribute_argument_n_type)
1433-
<< &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1434-
<< E->getSourceRange();
1433+
<< CI << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
14351434
else
14361435
Diag(AttrLoc, diag::err_attribute_argument_type)
1437-
<< &TmpAttr << AANT_ArgumentIntegerConstant
1438-
<< E->getSourceRange();
1436+
<< CI << AANT_ArgumentIntegerConstant << E->getSourceRange();
14391437
return;
14401438
}
14411439

@@ -1452,8 +1450,7 @@ void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
14521450

14531451
if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {
14541452
Diag(AttrLoc, diag::err_attribute_argument_n_type)
1455-
<< &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1456-
<< OE->getSourceRange();
1453+
<< CI << 2 << AANT_ArgumentIntegerConstant << OE->getSourceRange();
14571454
return;
14581455
}
14591456

@@ -1463,28 +1460,25 @@ void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
14631460
void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
14641461
Expr *ParamExpr) {
14651462
QualType ResultType = getFunctionOrMethodResultType(D);
1466-
1467-
AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
14681463
SourceLocation AttrLoc = CI.getLoc();
14691464

14701465
if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
14711466
Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1472-
<< &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1467+
<< CI << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
14731468
return;
14741469
}
14751470

14761471
ParamIdx Idx;
14771472
const auto *FuncDecl = cast<FunctionDecl>(D);
1478-
if (!checkFunctionOrMethodParameterIndex(FuncDecl, TmpAttr,
1473+
if (!checkFunctionOrMethodParameterIndex(FuncDecl, CI,
14791474
/*AttrArgNum=*/1, ParamExpr, Idx))
14801475
return;
14811476

14821477
QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
14831478
if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
14841479
!Ty->isAlignValT()) {
14851480
Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1486-
<< &TmpAttr
1487-
<< FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1481+
<< CI << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
14881482
return;
14891483
}
14901484

@@ -4383,7 +4377,6 @@ static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
43834377
}
43844378

43854379
void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
4386-
AlignValueAttr TmpAttr(Context, CI, E);
43874380
SourceLocation AttrLoc = CI.getLoc();
43884381

43894382
QualType T;
@@ -4397,7 +4390,7 @@ void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
43974390
if (!T->isDependentType() && !T->isAnyPointerType() &&
43984391
!T->isReferenceType() && !T->isMemberPointerType()) {
43994392
Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
4400-
<< &TmpAttr << T << D->getSourceRange();
4393+
<< CI << T << D->getSourceRange();
44014394
return;
44024395
}
44034396

clang/test/SemaCXX/align_value.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,17 @@ struct nope {
2424
// expected-note@+1 {{in instantiation of template class 'nope<long double, 4>' requested here}}
2525
nope<long double, 4> y2;
2626

27+
namespace GH26612 {
28+
// This used to crash while issuing the diagnostic about only applying to a
29+
// pointer or reference type.
30+
// FIXME: it would be ideal to only diagnose once rather than twice. We get one
31+
// diagnostic from explicit template arguments and another one for deduced
32+
// template arguments, which seems silly.
33+
template <class T>
34+
void f(T __attribute__((align_value(4))) x) {} // expected-warning 2 {{'align_value' attribute only applies to a pointer or reference ('int' is invalid)}}
35+
36+
void foo() {
37+
f<int>(0); // expected-note {{while substituting explicitly-specified template arguments into function template 'f'}} \
38+
expected-note {{while substituting deduced template arguments into function template 'f' [with T = int]}}
39+
}
40+
} // namespace GH26612

clang/test/SemaCXX/alloc-align-attr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,15 @@ void dependent_impl(int align) {
4747
dependent_param_func<int>(1);
4848
dependent_param_func<float>(1); // expected-note {{in instantiation of function template specialization 'dependent_param_func<float>' requested here}}
4949
}
50+
51+
namespace GH26612 {
52+
// This issue was about the align_value attribute, but alloc_align has the
53+
// same problematic code pattern, so is being fixed at the same time despite
54+
// not having the same crashing behavior.
55+
template <class T>
56+
__attribute__((alloc_align(1))) T f(T x); // expected-warning {{'alloc_align' attribute only applies to return values that are pointers or references}}
57+
58+
void foo() {
59+
f<int>(0); // expected-note {{in instantiation of function template specialization 'GH26612::f<int>' requested here}}
60+
}
61+
} // namespace GH26612

clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,14 @@ void test24() {
9191
atest5<s3>(); // expected-note {{in instantiation of function template specialization 'atest5<s3>' requested here}}
9292
}
9393

94+
namespace GH26612 {
95+
// This issue was about the align_value attribute, but assume_aligned has the
96+
// same problematic code pattern, so is being fixed at the same time despite
97+
// not having the same crashing behavior.
98+
template <class T>
99+
__attribute__((assume_aligned(4))) T f(T x); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers or references}}
100+
101+
void foo() {
102+
f<int>(0); // expected-note {{in instantiation of function template specialization 'GH26612::f<int>' requested here}}
103+
}
104+
} // namespace GH26612

0 commit comments

Comments
 (0)