Skip to content

Commit ab6ff0e

Browse files
authored
[CIR][NFC] Add errors for unhandled AggExprEmitter visitors (#155469)
There are a lot of required handlers in AggExprEmitter that are currently missing. Because the ASTVisitor has fallbacks, this means we just silently ignore whatever expressions are not explicitly handled. This patch adds handlers where we know they will be needed and just issues a diagnostic. This exposed failures in a few tests. In one case, we should have handled constant initialization earlier, which would have avoided going to the AggExprEmitter at all. I added a stub with a missing feature marker to allow that case to work as it had. Another test required us to ignore cast expressions that should be ignored, so I partially implemented the cast visitor. Finally, there's a case where the test was just accepting a bad result. I changed that case to XFAIL until it can be properly fixed.
1 parent de6f750 commit ab6ff0e

File tree

4 files changed

+207
-1
lines changed

4 files changed

+207
-1
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ struct MissingFeatures {
195195
static bool cirgenABIInfo() { return false; }
196196
static bool cleanupAfterErrorDiags() { return false; }
197197
static bool cleanupsToDeactivate() { return false; }
198+
static bool constEmitterAggILE() { return false; }
198199
static bool constEmitterArrayILE() { return false; }
199200
static bool constEmitterVectorILE() { return false; }
200201
static bool constantFoldSwitchStatement() { return false; }

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,205 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
8484
void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef<Expr *> args,
8585
FieldDecl *initializedFieldInUnion,
8686
Expr *arrayFiller);
87+
88+
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *e) {
89+
assert(!cir::MissingFeatures::aggValueSlotDestructedFlag());
90+
Visit(e->getSubExpr());
91+
}
92+
93+
// Stubs -- These should be moved up when they are implemented.
94+
void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *e) {
95+
// We shouldn't really get here, but we do because of missing handling for
96+
// emitting constant aggregate initializers. If we just ignore this, a
97+
// fallback handler will do the right thing.
98+
assert(!cir::MissingFeatures::constEmitterAggILE());
99+
return;
100+
}
101+
void VisitCastExpr(CastExpr *e) {
102+
switch (e->getCastKind()) {
103+
case CK_LValueToRValue:
104+
assert(!cir::MissingFeatures::aggValueSlotVolatile());
105+
[[fallthrough]];
106+
case CK_NoOp:
107+
case CK_UserDefinedConversion:
108+
case CK_ConstructorConversion:
109+
assert(cgf.getContext().hasSameUnqualifiedType(e->getSubExpr()->getType(),
110+
e->getType()) &&
111+
"Implicit cast types must be compatible");
112+
Visit(e->getSubExpr());
113+
break;
114+
default:
115+
cgf.cgm.errorNYI(e->getSourceRange(),
116+
std::string("AggExprEmitter: VisitCastExpr: ") +
117+
e->getCastKindName());
118+
break;
119+
}
120+
}
121+
void VisitStmt(Stmt *s) {
122+
cgf.cgm.errorNYI(s->getSourceRange(),
123+
std::string("AggExprEmitter::VisitStmt: ") +
124+
s->getStmtClassName());
125+
}
126+
void VisitParenExpr(ParenExpr *pe) {
127+
cgf.cgm.errorNYI(pe->getSourceRange(), "AggExprEmitter: VisitParenExpr");
128+
}
129+
void VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
130+
cgf.cgm.errorNYI(ge->getSourceRange(),
131+
"AggExprEmitter: VisitGenericSelectionExpr");
132+
}
133+
void VisitCoawaitExpr(CoawaitExpr *e) {
134+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCoawaitExpr");
135+
}
136+
void VisitCoyieldExpr(CoyieldExpr *e) {
137+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCoyieldExpr");
138+
}
139+
void VisitUnaryCoawait(UnaryOperator *e) {
140+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitUnaryCoawait");
141+
}
142+
void VisitUnaryExtension(UnaryOperator *e) {
143+
cgf.cgm.errorNYI(e->getSourceRange(),
144+
"AggExprEmitter: VisitUnaryExtension");
145+
}
146+
void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
147+
cgf.cgm.errorNYI(e->getSourceRange(),
148+
"AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");
149+
}
150+
void VisitConstantExpr(ConstantExpr *e) {
151+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitConstantExpr");
152+
}
153+
void VisitMemberExpr(MemberExpr *e) {
154+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitMemberExpr");
155+
}
156+
void VisitUnaryDeref(UnaryOperator *e) {
157+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitUnaryDeref");
158+
}
159+
void VisitStringLiteral(StringLiteral *e) {
160+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitStringLiteral");
161+
}
162+
void VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
163+
cgf.cgm.errorNYI(e->getSourceRange(),
164+
"AggExprEmitter: VisitCompoundLiteralExpr");
165+
}
166+
void VisitArraySubscriptExpr(ArraySubscriptExpr *e) {
167+
cgf.cgm.errorNYI(e->getSourceRange(),
168+
"AggExprEmitter: VisitArraySubscriptExpr");
169+
}
170+
void VisitPredefinedExpr(const PredefinedExpr *e) {
171+
cgf.cgm.errorNYI(e->getSourceRange(),
172+
"AggExprEmitter: VisitPredefinedExpr");
173+
}
174+
void VisitBinaryOperator(const BinaryOperator *e) {
175+
cgf.cgm.errorNYI(e->getSourceRange(),
176+
"AggExprEmitter: VisitBinaryOperator");
177+
}
178+
void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *e) {
179+
cgf.cgm.errorNYI(e->getSourceRange(),
180+
"AggExprEmitter: VisitPointerToDataMemberBinaryOperator");
181+
}
182+
void VisitBinAssign(const BinaryOperator *e) {
183+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinAssign");
184+
}
185+
void VisitBinComma(const BinaryOperator *e) {
186+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinComma");
187+
}
188+
void VisitBinCmp(const BinaryOperator *e) {
189+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinCmp");
190+
}
191+
void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {
192+
cgf.cgm.errorNYI(e->getSourceRange(),
193+
"AggExprEmitter: VisitCXXRewrittenBinaryOperator");
194+
}
195+
void VisitObjCMessageExpr(ObjCMessageExpr *e) {
196+
cgf.cgm.errorNYI(e->getSourceRange(),
197+
"AggExprEmitter: VisitObjCMessageExpr");
198+
}
199+
void VisitObjCIVarRefExpr(ObjCIvarRefExpr *e) {
200+
cgf.cgm.errorNYI(e->getSourceRange(),
201+
"AggExprEmitter: VisitObjCIVarRefExpr");
202+
}
203+
204+
void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e) {
205+
cgf.cgm.errorNYI(e->getSourceRange(),
206+
"AggExprEmitter: VisitDesignatedInitUpdateExpr");
207+
}
208+
void VisitAbstractConditionalOperator(const AbstractConditionalOperator *e) {
209+
cgf.cgm.errorNYI(e->getSourceRange(),
210+
"AggExprEmitter: VisitAbstractConditionalOperator");
211+
}
212+
void VisitChooseExpr(const ChooseExpr *e) {
213+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitChooseExpr");
214+
}
215+
void VisitCXXParenListInitExpr(CXXParenListInitExpr *e) {
216+
cgf.cgm.errorNYI(e->getSourceRange(),
217+
"AggExprEmitter: VisitCXXParenListInitExpr");
218+
}
219+
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *e,
220+
llvm::Value *outerBegin = nullptr) {
221+
cgf.cgm.errorNYI(e->getSourceRange(),
222+
"AggExprEmitter: VisitArrayInitLoopExpr");
223+
}
224+
void VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {
225+
cgf.cgm.errorNYI(e->getSourceRange(),
226+
"AggExprEmitter: VisitImplicitValueInitExpr");
227+
}
228+
void VisitNoInitExpr(NoInitExpr *e) {
229+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitNoInitExpr");
230+
}
231+
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
232+
cgf.cgm.errorNYI(dae->getSourceRange(),
233+
"AggExprEmitter: VisitCXXDefaultArgExpr");
234+
}
235+
void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
236+
cgf.cgm.errorNYI(die->getSourceRange(),
237+
"AggExprEmitter: VisitCXXDefaultInitExpr");
238+
}
239+
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *e) {
240+
cgf.cgm.errorNYI(e->getSourceRange(),
241+
"AggExprEmitter: VisitCXXInheritedCtorInitExpr");
242+
}
243+
void VisitLambdaExpr(LambdaExpr *e) {
244+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitLambdaExpr");
245+
}
246+
void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *e) {
247+
cgf.cgm.errorNYI(e->getSourceRange(),
248+
"AggExprEmitter: VisitCXXStdInitializerListExpr");
249+
}
250+
251+
void VisitExprWithCleanups(ExprWithCleanups *e) {
252+
cgf.cgm.errorNYI(e->getSourceRange(),
253+
"AggExprEmitter: VisitExprWithCleanups");
254+
}
255+
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
256+
cgf.cgm.errorNYI(e->getSourceRange(),
257+
"AggExprEmitter: VisitCXXScalarValueInitExpr");
258+
}
259+
void VisitCXXTypeidExpr(CXXTypeidExpr *e) {
260+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXTypeidExpr");
261+
}
262+
void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e) {
263+
cgf.cgm.errorNYI(e->getSourceRange(),
264+
"AggExprEmitter: VisitMaterializeTemporaryExpr");
265+
}
266+
void VisitOpaqueValueExpr(OpaqueValueExpr *e) {
267+
cgf.cgm.errorNYI(e->getSourceRange(),
268+
"AggExprEmitter: VisitOpaqueValueExpr");
269+
}
270+
271+
void VisitPseudoObjectExpr(PseudoObjectExpr *e) {
272+
cgf.cgm.errorNYI(e->getSourceRange(),
273+
"AggExprEmitter: VisitPseudoObjectExpr");
274+
}
275+
276+
void VisitVAArgExpr(VAArgExpr *e) {
277+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitVAArgExpr");
278+
}
279+
280+
void VisitCXXThrowExpr(const CXXThrowExpr *e) {
281+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXThrowExpr");
282+
}
283+
void VisitAtomicExpr(AtomicExpr *e) {
284+
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitAtomicExpr");
285+
}
87286
};
88287

89288
} // namespace

clang/test/CIR/CodeGen/statement-exprs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
66
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
77

8+
// This fails because of a non-ignored copy of an aggregate in test3.
9+
// XFAIL: *
10+
811
int f19(void) {
912
return ({ 3;;4;; });
1013
}

clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 -fopenacc -triple x86_64-linux-gnu -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir -triple x86_64-linux-pc %s -o - | FileCheck %s
1+
// RUN: not %clang_cc1 -fopenacc -triple x86_64-linux-gnu -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir -triple x86_64-linux-pc %s -o - | FileCheck %s
2+
3+
// This encounters NYI errors because of a non-ignored copy of an aggregate.
4+
// When that is fixed, the 'not' should be removed from the RUN line above.
25

36
struct NoCopyConstruct {};
47

0 commit comments

Comments
 (0)