@@ -7640,6 +7640,59 @@ static bool isMainVar(DeclarationName Name, VarDecl *VD) {
76407640 VD->isExternC());
76417641}
76427642
7643+ void Sema::CheckAsmLabel(Scope *S, Expr *E, StorageClass SC,
7644+ TypeSourceInfo *TInfo, VarDecl *NewVD) {
7645+
7646+ // Quickly return if the function does not have an `asm` attribute.
7647+ if (E == nullptr)
7648+ return;
7649+
7650+ // The parser guarantees this is a string.
7651+ StringLiteral *SE = cast<StringLiteral>(E);
7652+ StringRef Label = SE->getString();
7653+ QualType R = TInfo->getType();
7654+ if (S->getFnParent() != nullptr) {
7655+ switch (SC) {
7656+ case SC_None:
7657+ case SC_Auto:
7658+ Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
7659+ break;
7660+ case SC_Register:
7661+ // Local Named register
7662+ if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
7663+ DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
7664+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
7665+ break;
7666+ case SC_Static:
7667+ case SC_Extern:
7668+ case SC_PrivateExtern:
7669+ break;
7670+ }
7671+ } else if (SC == SC_Register) {
7672+ // Global Named register
7673+ if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
7674+ const auto &TI = Context.getTargetInfo();
7675+ bool HasSizeMismatch;
7676+
7677+ if (!TI.isValidGCCRegisterName(Label))
7678+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
7679+ else if (!TI.validateGlobalRegisterVariable(Label,
7680+ Context.getTypeSize(R),
7681+ HasSizeMismatch))
7682+ Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
7683+ else if (HasSizeMismatch)
7684+ Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
7685+ }
7686+
7687+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
7688+ Diag(TInfo->getTypeLoc().getBeginLoc(),
7689+ diag::err_asm_unsupported_register_type)
7690+ << TInfo->getTypeLoc().getSourceRange();
7691+ NewVD->setInvalidDecl(true);
7692+ }
7693+ }
7694+ }
7695+
76437696NamedDecl *Sema::ActOnVariableDeclarator(
76447697 Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
76457698 LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
@@ -8124,6 +8177,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
81248177 }
81258178 }
81268179
8180+ if (Expr *E = D.getAsmLabel()) {
8181+ // The parser guarantees this is a string.
8182+ StringLiteral *SE = cast<StringLiteral>(E);
8183+ StringRef Label = SE->getString();
8184+
8185+ // Insert the asm attribute.
8186+ NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
8187+ } else if (!ExtnameUndeclaredIdentifiers.empty()) {
8188+ llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
8189+ ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
8190+ if (I != ExtnameUndeclaredIdentifiers.end()) {
8191+ if (isDeclExternC(NewVD)) {
8192+ NewVD->addAttr(I->second);
8193+ ExtnameUndeclaredIdentifiers.erase(I);
8194+ } else
8195+ Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
8196+ << /*Variable*/1 << NewVD;
8197+ }
8198+ }
8199+
81278200 // Handle attributes prior to checking for duplicates in MergeVarDecl
81288201 ProcessDeclAttributes(S, NewVD, D);
81298202
@@ -8174,65 +8247,11 @@ NamedDecl *Sema::ActOnVariableDeclarator(
81748247 if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
81758248 NewVD->setInvalidDecl();
81768249
8177- // Handle GNU asm-label extension (encoded as an attribute).
8178- if (Expr *E = D.getAsmLabel()) {
8179- // The parser guarantees this is a string.
8180- StringLiteral *SE = cast<StringLiteral>(E);
8181- StringRef Label = SE->getString();
8182- if (S->getFnParent() != nullptr) {
8183- switch (SC) {
8184- case SC_None:
8185- case SC_Auto:
8186- Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
8187- break;
8188- case SC_Register:
8189- // Local Named register
8190- if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
8191- DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
8192- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
8193- break;
8194- case SC_Static:
8195- case SC_Extern:
8196- case SC_PrivateExtern:
8197- break;
8198- }
8199- } else if (SC == SC_Register) {
8200- // Global Named register
8201- if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
8202- const auto &TI = Context.getTargetInfo();
8203- bool HasSizeMismatch;
8204-
8205- if (!TI.isValidGCCRegisterName(Label))
8206- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
8207- else if (!TI.validateGlobalRegisterVariable(Label,
8208- Context.getTypeSize(R),
8209- HasSizeMismatch))
8210- Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
8211- else if (HasSizeMismatch)
8212- Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
8213- }
8214-
8215- if (!R->isIntegralType(Context) && !R->isPointerType()) {
8216- Diag(TInfo->getTypeLoc().getBeginLoc(),
8217- diag::err_asm_unsupported_register_type)
8218- << TInfo->getTypeLoc().getSourceRange();
8219- NewVD->setInvalidDecl(true);
8220- }
8221- }
8222-
8223- NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
8224- } else if (!ExtnameUndeclaredIdentifiers.empty()) {
8225- llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
8226- ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
8227- if (I != ExtnameUndeclaredIdentifiers.end()) {
8228- if (isDeclExternC(NewVD)) {
8229- NewVD->addAttr(I->second);
8230- ExtnameUndeclaredIdentifiers.erase(I);
8231- } else
8232- Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
8233- << /*Variable*/1 << NewVD;
8234- }
8235- }
8250+ // Check the ASM label here, as we need to know all other attributes of the
8251+ // Decl first. Otherwise, we can't know if the asm label refers to the
8252+ // host or device in a CUDA context. The device has other registers than
8253+ // host and we must know where the function will be placed.
8254+ CheckAsmLabel(S, D.getAsmLabel(), SC, TInfo, NewVD);
82368255
82378256 // Find the shadowed declaration before filtering for scope.
82388257 NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
0 commit comments