[CIR] Correctly handle annotate attribute on C++ constructors/destructors #1699
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes an issue where the
[[clang::annotate]]
attribute on C++ constructors (CXXConstructorDecl
) was not correctly lowered, and resolves a subsequent crash in thecir-to-llvm
pipeline caused by the initial fix.1. The Problem
There were two distinct problems:
Initial Bug: The
[[clang::annotate]]
attribute was completely ignored when applied to a C++ constructor. While it worked for regular functions, the specific code path for handlingCXXConstructorDecl
inCIRGenModule
did not process this attribute.Downstream Crash: After fixing the initial bug to generate the correct
annotations
andcir.global_annotations
in the CIR dialect, thecir-translate
tool would crash with a "redefinition of symbol" error for the annotation string (e.g.,.str.annotation
).2. Analysis and Root Cause
Cause of Initial Bug: In
CIRGenModule::emitGlobalDefinition
, the code path for constructors and destructors branches toABI->emitCXXStructor
. This path was missing the logic to check for anAnnotateAttr
and add it to thedeferredAnnotations
map, which is correctly handled for regularFunctionDecl
s.Cause of Downstream Crash: The
cir-to-llvm
lowering pipeline has two mechanisms for handling annotations:LoweringPrepare
pass processes thecir.global_annotations
attribute on theModuleOp
and generates the corresponding@llvm.global.annotations
array and its associated global string constants.cir-translate
binary also attempts to process the samecir.global_annotations
attribute.The issue was that
LoweringPreparePass
did not consume (remove) thecir.global_annotations
attribute after processing it. This left the attribute on the module, causing the later stage incir-translate
to re-process it, leading to the symbol redefinition crash.3. Implementation
This PR addresses both issues with two key changes:
In
CIRGenModule.cpp
:AnnotateAttr
has been added to theCXXConstructorDecl
/CXXDestructorDecl
path withinemitGlobalDefinition
. This ensures that constructor annotations are correctly identified and deferred for processing, just like regular functions.In
LoweringPreparePass
:buildGlobalAnnotationValues()
function successfully processes thecir.global_annotations
attribute and generates the necessary LLVM globals, the pass now removes thecir.global_annotations
attribute from theModuleOp
. This "consumes" the attribute, preventing any subsequent pass from redundantly processing it.4. Verification
With these changes, a C++ constructor with a
[[clang::annotate]]
attribute is now correctly lowered through the entire pipeline:cir
dialect) correctly contains both the localannotations
on thecir.func
and the module-levelcir.global_annotations
.cir-opt -cir-to-llvm
pass successfully lowers this to the LLVM dialect.cir-translate
tool successfully converts the LLVM dialect to LLVM IR text without crashing.@llvm.global.annotations
metadata for the constructor.This fix ensures that annotation metadata is preserved correctly and robustly for C++ constructors.