Skip to content

Commit 7272717

Browse files
committed
Warn about duplicate attributes
1 parent 299c364 commit 7272717

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6973,6 +6973,24 @@ static void handleVTablePointerAuthentication(Sema &S, Decl *D,
69736973
CustomDiscriminationValue));
69746974
}
69756975

6976+
static bool modularFormatIsSame(const ModularFormatAttr *Existing,
6977+
IdentifierInfo *ModularImplFn,
6978+
StringRef ImplName,
6979+
ArrayRef<StringRef> Aspects) {
6980+
if (Existing->getModularImplFn() != ModularImplFn)
6981+
return false;
6982+
if (Existing->getImplName() != ImplName)
6983+
return false;
6984+
if (Existing->aspects_size() != Aspects.size())
6985+
return false;
6986+
unsigned I = 0;
6987+
for (const auto &ExistingAspect : Existing->aspects()) {
6988+
if (ExistingAspect != Aspects[I++])
6989+
return false;
6990+
}
6991+
return true;
6992+
}
6993+
69766994
static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
69776995
StringRef ImplName;
69786996
if (!S.checkStringLiteralArgumentAttr(AL, 1, ImplName))
@@ -7000,8 +7018,18 @@ static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
70007018
// Store aspects sorted.
70017019
llvm::sort(Aspects);
70027020

7021+
IdentifierInfo *ModularImplFn = AL.getArgAsIdent(0)->getIdentifierInfo();
7022+
7023+
if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7024+
if (!modularFormatIsSame(Existing, ModularImplFn, ImplName, Aspects)) {
7025+
S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
7026+
S.Diag(Existing->getLocation(), diag::note_conflicting_attribute);
7027+
}
7028+
D->dropAttr<ModularFormatAttr>();
7029+
}
7030+
70037031
D->addAttr(::new (S.Context) ModularFormatAttr(
7004-
S.Context, AL, AL.getArgAsIdent(0)->getIdentifierInfo(), ImplName,
7032+
S.Context, AL, ModularImplFn, ImplName,
70057033
Aspects.data(), Aspects.size()));
70067034
}
70077035

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,15 @@ int dupe(const char *fmt, ...) __attribute__((modular_format(__modular_printf,
77
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}} \
88
// expected-error {{duplicate aspect 'int' in 'modular_format' attribute}}
99

10+
// Test with multiple identical attributes on the same declaration.
11+
int same_attr(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"), modular_format(__modular_printf, "__printf", "float"), format(printf, 1, 2))); // no-warning
12+
13+
// Test with multiple different attributes on the same declaration.
14+
int diff_attr(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"), format(printf, 1, 2), modular_format(__modular_printf, "__printf", "int"))); // expected-warning {{attribute 'modular_format' is already applied with different arguments}} expected-note {{conflicting attribute is here}}
15+
16+
int diff_attr2(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"), format(printf, 1, 2), modular_format(__modular_printf, "__other", "float"))); // expected-warning {{attribute 'modular_format' is already applied with different arguments}} expected-note {{conflicting attribute is here}}
17+
18+
int diff_attr3(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float"), format(printf, 1, 2), modular_format(__other, "__printf", "float"))); // expected-warning {{attribute 'modular_format' is already applied with different arguments}} expected-note {{conflicting attribute is here}}
19+
20+
// Test with same attributes but different aspect order.
21+
int diff_order(const char *fmt, ...) __attribute__((modular_format(__modular_printf, "__printf", "float", "int"), format(printf, 1, 2), modular_format(__modular_printf, "__printf", "int", "float"))); // no-warning

0 commit comments

Comments
 (0)