[clang] [Clang] Emit error for duplicate mangled names within a lambda (PR #107581)
Sander de Smalen via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 16 03:39:08 PDT 2024
================
@@ -4652,18 +4652,35 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
// If there are two attempts to define the same mangled name, issue an
// error.
- if (IsForDefinition && !Entry->isDeclaration()) {
- GlobalDecl OtherGD;
- // Check that GD is not yet in DiagnosedConflictingDefinitions is required
- // to make sure that we issue an error only once.
- if (lookupRepresentativeDecl(MangledName, OtherGD) &&
- (GD.getCanonicalDecl().getDecl() !=
- OtherGD.getCanonicalDecl().getDecl()) &&
- DiagnosedConflictingDefinitions.insert(GD).second) {
+ GlobalDecl OtherGD;
+ // Check that GD is not yet in DiagnosedConflictingDefinitions is required
+ // to make sure that we issue an error only once.
+ if (GD && lookupRepresentativeDecl(MangledName, OtherGD) &&
+ (GD.getCanonicalDecl().getDecl() !=
+ OtherGD.getCanonicalDecl().getDecl()) &&
+ DiagnosedConflictingDefinitions.insert(GD).second) {
+ if (IsForDefinition && !Entry->isDeclaration()) {
getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name)
<< MangledName;
getDiags().Report(OtherGD.getDecl()->getLocation(),
diag::note_previous_definition);
+ } else {
+ // For lambdas, it's possible to create the same mangled name from
+ // different function prototypes. For example, two FPTs may have
+ // identical types but incompatible function attributes which we should
+ // not allow.
+ auto *MD = dyn_cast<CXXMethodDecl>(D);
+ if (MD && MD->getParent()->isLambda()) {
+ const FunctionDecl *OtherFD =
+ cast_or_null<FunctionDecl>(OtherGD.getDecl());
+ if (FD && FD->hasPrototype() && OtherFD && OtherFD->hasPrototype()) {
+ if (FD->getType()->getAs<FunctionProtoType>() !=
+ OtherFD->getType()->getAs<FunctionProtoType>())
----------------
sdesmalen-arm wrote:
I don't understand why there's a need to check the `FunctionProtoType`s here, because the check `GD.getCanonicalDecl().getDecl() != OtherGD.getCanonicalDecl().getDecl()` has already checked if the declarations and types are the same.
Note that I tried a smaller change like this:
```
bool IsLambdaInstantiation =
D && isa<CXXMethodDecl>(D) &&
cast<CXXMethodDecl>(D)->getParent()->isLambda();
if (IsForDefinition && (!Entry->isDeclaration() || IsLambdaInstantiation)) {
```
And got the desired result. Would the above be sufficient or is there something this is not covering?
https://github.com/llvm/llvm-project/pull/107581
More information about the cfe-commits
mailing list