sunfish updated this revision to Diff 197215.
sunfish added a comment.
Implemented proper diagnostics for import_name/import_module on functions with
definitions, and updated the test.
I'm unsure of the `DIAG_SIZE_SEMA` change, but without it, the build fails with
this error:
/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp:72:3: error: static assertion
failed: DIAG_SIZE_SEMA is insufficient to contain all diagnostics, it may need
to be made larger in DiagnosticIDs.h.
static_assert(
\
^
/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp:88:1: note: in expansion of
macro ‘VALIDATE_DIAG_SIZE’
VALIDATE_DIAG_SIZE(SEMA)
^~~~~~~~~~~~~~~~~~
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59520/new/
https://reviews.llvm.org/D59520
Files:
include/clang/Basic/DiagnosticIDs.h
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-wasm.c
Index: test/Sema/attr-wasm.c
===================================================================
--- test/Sema/attr-wasm.c
+++ test/Sema/attr-wasm.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fsyntax-only -verify %s
+
+void name_a() __attribute__((import_name)); //expected-error {{'import_name' attribute takes one argument}}
+
+int name_b __attribute__((import_name("foo"))); //expected-error {{'import_name' attribute only applies to functions}}
+
+void name_c() __attribute__((import_name("foo", "bar"))); //expected-error {{'import_name' attribute takes one argument}}
+
+void name_d() __attribute__((import_name("foo", "bar", "qux"))); //expected-error {{'import_name' attribute takes one argument}}
+
+void name_z() __attribute__((import_name("foo")));
+
+void module_a() __attribute__((import_module)); //expected-error {{'import_module' attribute takes one argument}}
+
+int module_b __attribute__((import_module("foo"))); //expected-error {{'import_module' attribute only applies to functions}}
+
+void module_c() __attribute__((import_module("foo", "bar"))); //expected-error {{'import_module' attribute takes one argument}}
+
+void module_d() __attribute__((import_module("foo", "bar", "qux"))); //expected-error {{'import_module' attribute takes one argument}}
+
+void module_z() __attribute__((import_module("foo")));
+
+void both() __attribute__((import_name("foo"), import_module("bar")));
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5755,50 +5755,80 @@
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
}
-static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!isFunctionOrMethod(D)) {
- S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
- << "'import_module'" << ExpectedFunction;
- return;
+WebAssemblyImportModuleAttr *
+Sema::mergeImportModuleAttr(Decl *D, SourceRange Range,
+ StringRef Name,
+ unsigned AttrSpellingListIndex) {
+ auto *FD = cast<FunctionDecl>(D);
+
+ if (WebAssemblyImportModuleAttr *ExistingAttr =
+ FD->getAttr<WebAssemblyImportModuleAttr>()) {
+ if (ExistingAttr->getImportModule() == Name)
+ return nullptr;
+ Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import_module);
+ Diag(Range.getBegin(), diag::note_previous_attribute);
+ return nullptr;
+ }
+ if (FD->hasBody()) {
+ Diag(Range.getBegin(), diag::warn_import_module_on_definition);
+ return nullptr;
}
+ return ::new (Context) WebAssemblyImportModuleAttr(Range, Context, Name,
+ AttrSpellingListIndex);
+}
+WebAssemblyImportNameAttr *
+Sema::mergeImportNameAttr(Decl *D, SourceRange Range,
+ StringRef Name,
+ unsigned AttrSpellingListIndex) {
auto *FD = cast<FunctionDecl>(D);
- if (FD->isThisDeclarationADefinition()) {
- S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
- return;
+
+ if (WebAssemblyImportNameAttr *ExistingAttr =
+ FD->getAttr<WebAssemblyImportNameAttr>()) {
+ if (ExistingAttr->getImportName() == Name)
+ return nullptr;
+ Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import_name);
+ Diag(Range.getBegin(), diag::note_previous_attribute);
+ return nullptr;
+ }
+ if (FD->hasBody()) {
+ Diag(Range.getBegin(), diag::warn_import_name_on_definition);
+ return nullptr;
}
+ return ::new (Context) WebAssemblyImportNameAttr(Range, Context, Name,
+ AttrSpellingListIndex);
+}
+
+static void
+handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ auto *FD = cast<FunctionDecl>(D);
StringRef Str;
SourceLocation ArgLoc;
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
return;
- FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr(
- AL.getRange(), S.Context, Str,
- AL.getAttributeSpellingListIndex()));
+ unsigned Index = AL.getAttributeSpellingListIndex();
+ WebAssemblyImportModuleAttr *NewAttr =
+ S.mergeImportModuleAttr(FD, AL.getRange(), Str, Index);
+ if (NewAttr)
+ FD->addAttr(NewAttr);
}
-static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!isFunctionOrMethod(D)) {
- S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
- << "'import_name'" << ExpectedFunction;
- return;
- }
-
+static void
+handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
auto *FD = cast<FunctionDecl>(D);
- if (FD->isThisDeclarationADefinition()) {
- S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
- return;
- }
StringRef Str;
SourceLocation ArgLoc;
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
return;
- FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(
- AL.getRange(), S.Context, Str,
- AL.getAttributeSpellingListIndex()));
+ unsigned Index = AL.getAttributeSpellingListIndex();
+ WebAssemblyImportNameAttr *NewAttr =
+ S.mergeImportNameAttr(FD, AL.getRange(), Str, Index);
+ if (NewAttr)
+ FD->addAttr(NewAttr);
}
static void handleRISCVInterruptAttr(Sema &S, Decl *D,
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2500,6 +2500,14 @@
NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
NewAttr = S.mergeNoSpeculativeLoadHardeningAttr(D, *SLHA);
+ else if (const auto *IMA = dyn_cast<WebAssemblyImportModuleAttr>(Attr))
+ NewAttr = S.mergeImportModuleAttr(D, IMA->getRange(),
+ IMA->getImportModule(),
+ AttrSpellingListIndex);
+ else if (const auto *INA = dyn_cast<WebAssemblyImportNameAttr>(Attr))
+ NewAttr = S.mergeImportNameAttr(D, INA->getRange(),
+ INA->getImportName(),
+ AttrSpellingListIndex);
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2613,6 +2613,12 @@
const InternalLinkageAttr &AL);
CommonAttr *mergeCommonAttr(Decl *D, const ParsedAttr &AL);
CommonAttr *mergeCommonAttr(Decl *D, const CommonAttr &AL);
+ WebAssemblyImportNameAttr *mergeImportNameAttr(
+ Decl *D, SourceRange Range, StringRef Name,
+ unsigned AttrSpellingListIndex);
+ WebAssemblyImportModuleAttr *mergeImportModuleAttr(
+ Decl *D, SourceRange Range, StringRef Name,
+ unsigned AttrSpellingListIndex);
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -9646,4 +9646,13 @@
"%select{non-pointer|function pointer|void pointer}0 argument to "
"'__builtin_launder' is not allowed">;
+def warn_mismatched_import_module : Warning<
+ "import module does not match previous declaration">;
+def warn_mismatched_import_name : Warning<
+ "import name does not match previous declaration">;
+def warn_import_module_on_definition : Warning<
+ "import module cannot be applied to a function with a definition">;
+def warn_import_name_on_definition : Warning<
+ "import name cannot be applied to a function with a definition">;
+
} // end of sema component.
Index: include/clang/Basic/DiagnosticIDs.h
===================================================================
--- include/clang/Basic/DiagnosticIDs.h
+++ include/clang/Basic/DiagnosticIDs.h
@@ -36,7 +36,7 @@
DIAG_SIZE_AST = 150,
DIAG_SIZE_COMMENT = 100,
DIAG_SIZE_CROSSTU = 100,
- DIAG_SIZE_SEMA = 3500,
+ DIAG_SIZE_SEMA = 3504,
DIAG_SIZE_ANALYSIS = 100,
DIAG_SIZE_REFACTORING = 1000,
};
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits