Skip to content

Commit 299c364

Browse files
committed
Add error for duplicate modular_format aspects and tests
1 parent 36b4e84 commit 299c364

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13066,6 +13066,9 @@ def err_get_vtable_pointer_requires_complete_type
1306613066
def err_modular_format_attribute_no_format
1306713067
: Error<"'modular_format' attribute requires 'format' attribute">;
1306813068

13069+
def err_modular_format_duplicate_aspect
13070+
: Error<"duplicate aspect '%0' in 'modular_format' attribute">;
13071+
1306913072
// SYCL-specific diagnostics
1307013073
def warn_sycl_kernel_num_of_template_params : Warning<
1307113074
"'sycl_kernel' attribute only applies to a function template with at least"

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6978,16 +6978,27 @@ static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
69786978
if (!S.checkStringLiteralArgumentAttr(AL, 1, ImplName))
69796979
return;
69806980
SmallVector<StringRef> Aspects;
6981+
llvm::DenseSet<StringRef> SeenAspects;
6982+
bool HasDuplicate = false;
69816983
for (unsigned I = 2, E = AL.getNumArgs(); I != E; ++I) {
69826984
StringRef Aspect;
69836985
if (!S.checkStringLiteralArgumentAttr(AL, I, Aspect))
69846986
return;
6987+
if (!SeenAspects.insert(Aspect).second) {
6988+
S.Diag(AL.getArgAsExpr(I)->getExprLoc(),
6989+
diag::err_modular_format_duplicate_aspect)
6990+
<< Aspect;
6991+
HasDuplicate = true;
6992+
continue;
6993+
}
69856994
Aspects.push_back(Aspect);
69866995
}
69876996

6988-
// Store aspects sorted and without duplicates.
6997+
if (HasDuplicate)
6998+
return;
6999+
7000+
// Store aspects sorted.
69897001
llvm::sort(Aspects);
6990-
Aspects.erase(llvm::unique(Aspects), Aspects.end());
69917002

69927003
D->addAttr(::new (S.Context) ModularFormatAttr(
69937004
S.Context, AL, AL.getArgAsIdent(0)->getIdentifierInfo(), ImplName,

clang/test/Sema/attr-modular-format.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
int printf(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"))); // no-error
44
int myprintf(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"))); // expected-error {{'modular_format' attribute requires 'format' attribute}}
55

6+
int dupe(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float", "int", "float"), format(printf, 1, 2))); // expected-error {{duplicate aspect 'float' in 'modular_format' attribute}}
7+
int multi_dupe(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float", "int", "float", "int"), format(printf, 1, 2))); // expected-error {{duplicate aspect 'float' in 'modular_format' attribute}} \
8+
// expected-error {{duplicate aspect 'int' in 'modular_format' attribute}}
9+

0 commit comments

Comments
 (0)