================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits