Skip to content

Commit 8afd704

Browse files
Use the most recent declaration as the canonical one for lifetimebound
1 parent 8d5ff55 commit 8afd704

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,17 @@ static bool isNormalAssignmentOperator(const FunctionDecl *FD) {
523523
return false;
524524
}
525525

526+
static const FunctionDecl *getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD) {
527+
return FD->getMostRecentDecl();
528+
}
529+
530+
static const CXXMethodDecl *getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD) {
531+
const FunctionDecl* FD = CMD;
532+
return cast<CXXMethodDecl>(getDeclWithMergedLifetimeBoundAttrs(FD));
533+
}
534+
526535
bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
536+
FD = getDeclWithMergedLifetimeBoundAttrs(FD);
527537
const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
528538
if (!TSI)
529539
return false;
@@ -636,7 +646,7 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call,
636646
}
637647
}
638648

639-
const FunctionDecl *CanonCallee = Callee->getCanonicalDecl();
649+
const FunctionDecl *CanonCallee = getDeclWithMergedLifetimeBoundAttrs(Callee);
640650
unsigned NP = std::min(Callee->getNumParams(), CanonCallee->getNumParams());
641651
for (unsigned I = 0, N = std::min<unsigned>(NP, Args.size()); I != N; ++I) {
642652
Expr *Arg = Args[I];
@@ -1236,6 +1246,7 @@ static AnalysisResult analyzePathForGSLPointer(const IndirectLocalPath &Path,
12361246
}
12371247

12381248
static bool isAssignmentOperatorLifetimeBound(CXXMethodDecl *CMD) {
1249+
CMD = getDeclWithMergedLifetimeBoundAttrs(CMD);
12391250
return CMD && isNormalAssignmentOperator(CMD) && CMD->param_size() == 1 &&
12401251
CMD->getParamDecl(0)->hasAttr<LifetimeBoundAttr>();
12411252
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3227,44 +3227,46 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
32273227
if (!foundAny) New->dropAttrs();
32283228
}
32293229

3230+
// Returns the number of added attributes.
32303231
template <class T>
3231-
static unsigned propagateAttribute(ParmVarDecl *toDecl,
3232-
const ParmVarDecl *fromDecl, Sema &S) {
3232+
static unsigned propagateAttribute(ParmVarDecl *To,
3233+
const ParmVarDecl *From, Sema &S) {
32333234
unsigned found = 0;
3234-
for (const auto *I : fromDecl->specific_attrs<T>()) {
3235-
if (!DeclHasAttr(toDecl, I)) {
3235+
for (const auto *I : From->specific_attrs<T>()) {
3236+
if (!DeclHasAttr(To, I)) {
32363237
T *newAttr = cast<T>(I->clone(S.Context));
32373238
newAttr->setInherited(true);
3238-
toDecl->addAttr(newAttr);
3239+
To->addAttr(newAttr);
32393240
++found;
32403241
}
32413242
}
32423243
return found;
32433244
}
32443245

32453246
template <class F>
3246-
static void propagateAttributes(ParmVarDecl *toDecl,
3247-
const ParmVarDecl *fromDecl, F &&propagator) {
3248-
if (!fromDecl->hasAttrs()) {
3247+
static void propagateAttributes(ParmVarDecl *To,
3248+
const ParmVarDecl *From, F &&propagator) {
3249+
if (!From->hasAttrs()) {
32493250
return;
32503251
}
32513252

3252-
bool foundAny = toDecl->hasAttrs();
3253+
bool foundAny = To->hasAttrs();
32533254

32543255
// Ensure that any moving of objects within the allocated map is
32553256
// done before we process them.
32563257
if (!foundAny)
3257-
toDecl->setAttrs(AttrVec());
3258+
To->setAttrs(AttrVec());
32583259

3259-
foundAny |= std::forward<F>(propagator)(toDecl, fromDecl) != 0;
3260+
foundAny |= std::forward<F>(propagator)(To, From) != 0;
32603261

32613262
if (!foundAny)
3262-
toDecl->dropAttrs();
3263+
To->dropAttrs();
32633264
}
32643265

32653266
/// mergeParamDeclAttributes - Copy attributes from the old parameter
32663267
/// to the new one.
3267-
static void mergeParamDeclAttributes(ParmVarDecl *newDecl, ParmVarDecl *oldDecl,
3268+
static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
3269+
const ParmVarDecl *oldDecl,
32683270
Sema &S) {
32693271
// C++11 [dcl.attr.depend]p2:
32703272
// The first declaration of a function shall specify the
@@ -3284,23 +3286,15 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl, ParmVarDecl *oldDecl,
32843286
diag::note_carries_dependency_missing_first_decl) << 1/*Param*/;
32853287
}
32863288

3287-
// Forward propagation (from old parameter to new)
32883289
propagateAttributes(
3289-
newDecl, oldDecl, [&S](ParmVarDecl *toDecl, const ParmVarDecl *fromDecl) {
3290-
unsigned found = 0;
3291-
found += propagateAttribute<InheritableParamAttr>(toDecl, fromDecl, S);
3292-
return found;
3293-
});
3294-
3295-
// Backward propagation (from new parameter to old)
3296-
propagateAttributes(
3297-
oldDecl, newDecl, [&S](ParmVarDecl *toDecl, const ParmVarDecl *fromDecl) {
3290+
newDecl, oldDecl, [&S](ParmVarDecl *To, const ParmVarDecl *From) {
32983291
unsigned found = 0;
3292+
found += propagateAttribute<InheritableParamAttr>(To, From, S);
32993293
// Propagate the lifetimebound attribute from parameters to the
3300-
// canonical declaration. Note that this doesn't include the implicit
3294+
// most recent declaration. Note that this doesn't include the implicit
33013295
// 'this' parameter, as the attribute is applied to the function type in
33023296
// that case.
3303-
found += propagateAttribute<LifetimeBoundAttr>(toDecl, fromDecl, S);
3297+
found += propagateAttribute<LifetimeBoundAttr>(To, From, S);
33043298
return found;
33053299
});
33063300
}
@@ -4356,8 +4350,8 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
43564350
mergeDeclAttributes(newMethod, oldMethod, MergeKind);
43574351

43584352
// Merge attributes from the parameters.
4359-
ObjCMethodDecl::param_iterator oi = oldMethod->param_begin(),
4360-
oe = oldMethod->param_end();
4353+
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
4354+
oe = oldMethod->param_end();
43614355
for (ObjCMethodDecl::param_iterator
43624356
ni = newMethod->param_begin(), ne = newMethod->param_end();
43634357
ni != ne && oi != oe; ++ni, ++oi)
@@ -6981,6 +6975,7 @@ static void checkInheritableAttr(Sema &S, NamedDecl &ND) {
69816975
static void checkLifetimeBoundAttr(Sema &S, NamedDecl &ND) {
69826976
// Check the attributes on the function type and function params, if any.
69836977
if (const auto *FD = dyn_cast<FunctionDecl>(&ND)) {
6978+
FD = FD->getMostRecentDecl();
69846979
// Don't declare this variable in the second operand of the for-statement;
69856980
// GCC miscompiles that by ending its lifetime before evaluating the
69866981
// third operand. See gcc.gnu.org/PR86769.

0 commit comments

Comments
 (0)