Skip to content

Commit f1d6baf

Browse files
Undo changes to inferLifetimeBoundAttribute and use mergeParamDeclAttributes instead
1 parent 4dfad6c commit f1d6baf

File tree

2 files changed

+68
-45
lines changed

2 files changed

+68
-45
lines changed

clang/lib/Sema/SemaAttr.cpp

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) {
217217
}
218218

219219
void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) {
220-
unsigned NumParams = FD->getNumParams();
221-
if (NumParams == 0)
220+
if (FD->getNumParams() == 0)
222221
return;
223222

224223
if (unsigned BuiltinID = FD->getBuiltinID()) {
@@ -240,13 +239,18 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) {
240239
default:
241240
break;
242241
}
243-
} else if (auto *CMD = dyn_cast<CXXMethodDecl>(FD)) {
244-
const CXXRecordDecl *CRD = CMD->getParent();
245-
if (CRD->isInStdNamespace() && CRD->getIdentifier() &&
246-
isa<CXXConstructorDecl>(CMD)) {
242+
return;
243+
}
244+
if (auto *CMD = dyn_cast<CXXMethodDecl>(FD)) {
245+
const auto *CRD = CMD->getParent();
246+
if (!CRD->isInStdNamespace() || !CRD->getIdentifier())
247+
return;
248+
249+
if (isa<CXXConstructorDecl>(CMD)) {
247250
auto *Param = CMD->getParamDecl(0);
248-
if (!Param->hasAttr<LifetimeBoundAttr>() &&
249-
CRD->getName() == "basic_string_view" &&
251+
if (Param->hasAttr<LifetimeBoundAttr>())
252+
return;
253+
if (CRD->getName() == "basic_string_view" &&
250254
Param->getType()->isPointerType()) {
251255
// construct from a char array pointed by a pointer.
252256
// basic_string_view(const CharT* s);
@@ -262,20 +266,6 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) {
262266
LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
263267
}
264268
}
265-
} else if (auto *CanonDecl = FD->getCanonicalDecl(); FD != CanonDecl) {
266-
// Propagate the lifetimebound attribute from parameters to the canonical
267-
// declaration.
268-
// Note that this doesn't include the implicit 'this' parameter, as the
269-
// attribute is applied to the function type in that case.
270-
unsigned NP = std::min(NumParams, CanonDecl->getNumParams());
271-
for (unsigned I = 0; I < NP; ++I) {
272-
auto *CanonParam = CanonDecl->getParamDecl(I);
273-
if (!CanonParam->hasAttr<LifetimeBoundAttr>() &&
274-
FD->getParamDecl(I)->hasAttr<LifetimeBoundAttr>()) {
275-
CanonParam->addAttr(LifetimeBoundAttr::CreateImplicit(
276-
Context, CanonParam->getLocation()));
277-
}
278-
}
279269
}
280270
}
281271

clang/lib/Sema/SemaDecl.cpp

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

3230+
template <class T>
3231+
static unsigned propagateAttribute(ParmVarDecl *toDecl,
3232+
const ParmVarDecl *fromDecl, Sema &S) {
3233+
unsigned found = 0;
3234+
for (const auto *I : fromDecl->specific_attrs<T>()) {
3235+
if (!DeclHasAttr(toDecl, I)) {
3236+
T *newAttr = cast<T>(I->clone(S.Context));
3237+
newAttr->setInherited(true);
3238+
toDecl->addAttr(newAttr);
3239+
++found;
3240+
}
3241+
}
3242+
return found;
3243+
}
3244+
3245+
template <class F>
3246+
static void propagateAttributes(ParmVarDecl *toDecl,
3247+
const ParmVarDecl *fromDecl, F &&propagator) {
3248+
if (!fromDecl->hasAttrs()) {
3249+
return;
3250+
}
3251+
3252+
bool foundAny = toDecl->hasAttrs();
3253+
3254+
// Ensure that any moving of objects within the allocated map is
3255+
// done before we process them.
3256+
if (!foundAny)
3257+
toDecl->setAttrs(AttrVec());
3258+
3259+
foundAny |= std::forward<F>(propagator)(toDecl, fromDecl) != 0;
3260+
3261+
if (!foundAny)
3262+
toDecl->dropAttrs();
3263+
}
3264+
32303265
/// mergeParamDeclAttributes - Copy attributes from the old parameter
32313266
/// to the new one.
3232-
static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
3233-
const ParmVarDecl *oldDecl,
3267+
static void mergeParamDeclAttributes(ParmVarDecl *newDecl, ParmVarDecl *oldDecl,
32343268
Sema &S) {
32353269
// C++11 [dcl.attr.depend]p2:
32363270
// The first declaration of a function shall specify the
@@ -3250,26 +3284,25 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
32503284
diag::note_carries_dependency_missing_first_decl) << 1/*Param*/;
32513285
}
32523286

3253-
if (!oldDecl->hasAttrs())
3254-
return;
3255-
3256-
bool foundAny = newDecl->hasAttrs();
3257-
3258-
// Ensure that any moving of objects within the allocated map is
3259-
// done before we process them.
3260-
if (!foundAny) newDecl->setAttrs(AttrVec());
3261-
3262-
for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) {
3263-
if (!DeclHasAttr(newDecl, I)) {
3264-
InheritableAttr *newAttr =
3265-
cast<InheritableParamAttr>(I->clone(S.Context));
3266-
newAttr->setInherited(true);
3267-
newDecl->addAttr(newAttr);
3268-
foundAny = true;
3269-
}
3270-
}
3287+
// Forward propagation (from old parameter to new)
3288+
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+
});
32713294

3272-
if (!foundAny) newDecl->dropAttrs();
3295+
// Backward propagation (from new parameter to old)
3296+
propagateAttributes(
3297+
oldDecl, newDecl, [&S](ParmVarDecl *toDecl, const ParmVarDecl *fromDecl) {
3298+
unsigned found = 0;
3299+
// Propagate the lifetimebound attribute from parameters to the
3300+
// canonical declaration. Note that this doesn't include the implicit
3301+
// 'this' parameter, as the attribute is applied to the function type in
3302+
// that case.
3303+
found += propagateAttribute<LifetimeBoundAttr>(toDecl, fromDecl, S);
3304+
return found;
3305+
});
32733306
}
32743307

32753308
static bool EquivalentArrayTypes(QualType Old, QualType New,
@@ -4323,8 +4356,8 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
43234356
mergeDeclAttributes(newMethod, oldMethod, MergeKind);
43244357

43254358
// Merge attributes from the parameters.
4326-
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
4327-
oe = oldMethod->param_end();
4359+
ObjCMethodDecl::param_iterator oi = oldMethod->param_begin(),
4360+
oe = oldMethod->param_end();
43284361
for (ObjCMethodDecl::param_iterator
43294362
ni = newMethod->param_begin(), ne = newMethod->param_end();
43304363
ni != ne && oi != oe; ++ni, ++oi)

0 commit comments

Comments
 (0)