@@ -10466,6 +10466,77 @@ static bool isStdBuiltin(ASTContext &Ctx, FunctionDecl *FD,
1046610466 }
1046710467}
1046810468
10469+ static void rebuildBoundAttributedTypes(Sema &S, FunctionDecl *FD) {
10470+ struct ReplaceParams : public TreeTransform<ReplaceParams> {
10471+ using BaseTransform = TreeTransform<ReplaceParams>;
10472+ FunctionDecl *FD;
10473+
10474+ explicit ReplaceParams(Sema &SemaRef, FunctionDecl *FD)
10475+ : BaseTransform(SemaRef), FD(FD) {}
10476+
10477+ bool AlwaysRebuild() { return true; }
10478+
10479+ ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
10480+ const auto *OldParam = dyn_cast<ParmVarDecl>(E->getDecl());
10481+ if (!OldParam)
10482+ return BaseTransform::TransformDeclRefExpr(E);
10483+ auto *NewParam = FD->getParamDecl(OldParam->getFunctionScopeIndex());
10484+ return SemaRef.BuildDeclRefExpr(NewParam, E->getType(), E->getValueKind(),
10485+ E->getNameInfo());
10486+ }
10487+ } Transform(S, FD);
10488+
10489+ auto RebuildBoundAttributeType = [&](QualType Ty) {
10490+ if (Ty->isBoundsAttributedType() ||
10491+ (Ty->isPointerType() &&
10492+ Ty->getPointeeType()->isBoundsAttributedType())) {
10493+ return Transform.TransformType(Ty);
10494+ }
10495+ return Ty;
10496+ };
10497+
10498+ QualType OldRetTy = FD->getReturnType();
10499+ QualType NewRetTy = RebuildBoundAttributeType(OldRetTy);
10500+ bool Updated = NewRetTy != OldRetTy;
10501+
10502+ llvm::SmallVector<QualType, 4> NewParamTys;
10503+ NewParamTys.reserve(FD->getNumParams());
10504+ for (unsigned I = 0; I < FD->getNumParams(); ++I) {
10505+ ParmVarDecl *Param = FD->getParamDecl(I);
10506+ QualType OldTy = Param->getType();
10507+ QualType NewTy = RebuildBoundAttributeType(OldTy);
10508+
10509+ NewParamTys.push_back(NewTy);
10510+
10511+ if (NewTy == OldTy)
10512+ continue;
10513+
10514+ Param->setType(NewTy);
10515+ Updated = true;
10516+
10517+ // If this param is a count attributed type or a pointer to it (Deref is
10518+ // true), we need to recreate DependerDeclsAttr for its dependent
10519+ // parameters.
10520+ bool Deref = false;
10521+ const auto *CATy = NewTy->getAs<CountAttributedType>();
10522+ if (!CATy && NewTy->isPointerType()) {
10523+ Deref = true;
10524+ CATy = NewTy->getPointeeType()->getAs<CountAttributedType>();
10525+ }
10526+ if (CATy)
10527+ S.AttachDependerDeclsAttr(Param, CATy, Deref);
10528+ }
10529+
10530+ if (!Updated)
10531+ return;
10532+
10533+ // TODO: We could keep the typeof/typedef sugars.
10534+ const auto *OldFPT = FD->getType()->castAs<FunctionProtoType>();
10535+ QualType NewFPT = S.Context.getFunctionType(NewRetTy, NewParamTys,
10536+ OldFPT->getExtProtoInfo());
10537+ FD->setType(NewFPT);
10538+ }
10539+
1046910540NamedDecl*
1047010541Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1047110542 TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -11025,11 +11096,64 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1102511096 // @endcode
1102611097
1102711098 // Synthesize a parameter for each argument type.
11028- for (const auto &AI : FT->param_types()) {
11029- ParmVarDecl *Param =
11030- BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), AI);
11031- Param->setScopeInfo(0, Params.size());
11032- Params.push_back(Param);
11099+
11100+ /* TO_UPSTREAM(BoundsSafety) ON */
11101+ if (getLangOpts().BoundsSafetyAttributes) {
11102+ // If the parameters are used as dependent variables, we can synthesize
11103+ // named parameters for use in the declaration. Named dependent variables
11104+ // let us generate better diagnostics for the user (e.g.,
11105+ // __counted_by(len) instead of __counted_by()). Otherwise, just
11106+ // synthesize unnamed parameters.
11107+ llvm::SmallVector<const ParmVarDecl *, 4> NamedParams(FT->getNumParams(),
11108+ nullptr);
11109+ auto AddNamedParamFromDependentType = [&](QualType Ty) {
11110+ const auto *BAT = Ty->getAs<BoundsAttributedType>();
11111+ if (!BAT && Ty->isPointerType())
11112+ BAT = Ty->getPointeeType()->getAs<BoundsAttributedType>();
11113+ if (!BAT)
11114+ return;
11115+ for (const auto &DD : BAT->dependent_decls()) {
11116+ if (const auto *PVD = dyn_cast<ParmVarDecl>(DD.getDecl()))
11117+ NamedParams[PVD->getFunctionScopeIndex()] = PVD;
11118+ }
11119+ };
11120+ AddNamedParamFromDependentType(FT->getReturnType());
11121+ for (QualType ParamTy : FT->param_types())
11122+ AddNamedParamFromDependentType(ParamTy);
11123+
11124+ // Temporarily put parameter variables in the translation unit, not the
11125+ // enclosing context. This is what Sema::ActOnParamDeclarator() already
11126+ // does when declaring a function without a typedef/typeof. In
11127+ // BoundsSafety, we do it to allow creating references to the parameters
11128+ // when rebuilding the count expression. Otherwise, creating such
11129+ // references triggers an error.
11130+ for (unsigned I = 0; I < FT->getNumParams(); ++I) {
11131+ QualType Ty = FT->getParamType(I);
11132+ const ParmVarDecl *NamedParam = NamedParams[I];
11133+ ParmVarDecl *Param;
11134+ if (!NamedParam) {
11135+ Param = BuildParmVarDeclForTypedef(Context.getTranslationUnitDecl(),
11136+ D.getIdentifierLoc(), Ty);
11137+ } else {
11138+ SourceLocation Loc = D.getIdentifierLoc();
11139+ Param = ParmVarDecl::Create(Context, Context.getTranslationUnitDecl(),
11140+ Loc, Loc, NamedParam->getIdentifier(), Ty,
11141+ Context.getTrivialTypeSourceInfo(Ty, Loc),
11142+ SC_None, nullptr);
11143+ Param->setImplicit();
11144+ }
11145+ Param->setScopeInfo(0, Params.size());
11146+ Params.push_back(Param);
11147+ }
11148+ }
11149+ /* TO_UPSTREAM(BoundsSafety) OFF */
11150+ else {
11151+ for (const auto &AI : FT->param_types()) {
11152+ ParmVarDecl *Param =
11153+ BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), AI);
11154+ Param->setScopeInfo(0, Params.size());
11155+ Params.push_back(Param);
11156+ }
1103311157 }
1103411158 } else {
1103511159 assert(R->isFunctionNoProtoType() && NewFD->getNumParams() == 0 &&
@@ -11040,6 +11164,20 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1104011164 NewFD->setParams(Params);
1104111165
1104211166 /* TO_UPSTREAM(BoundsSafety) ON*/
11167+ if (getLangOpts().BoundsSafetyAttributes) {
11168+ if (!D.isFunctionDeclarator() && R->isFunctionProtoType()) {
11169+ // The function is being declared with a typedef/typeof. We need to
11170+ // rebuild the bound attributed types, so that their expression refer the
11171+ // to the new parameters.
11172+ rebuildBoundAttributedTypes(*this, NewFD);
11173+
11174+ for (ParmVarDecl *Param : Params) {
11175+ assert(Param->getDeclContext() == Context.getTranslationUnitDecl());
11176+ Param->setDeclContext(NewFD);
11177+ }
11178+ }
11179+ }
11180+
1104311181 if (getLangOpts().BoundsSafety) {
1104411182 // This is a good place to make sure that no array parameter has decayed
1104511183 // to a __single pointer. Annoyingly, we can't do this when parameters are
0 commit comments