Skip to content

Commit 11bc5b6

Browse files
Vedant2005goyalvgvassilev
authored andcommitted
Fix dyn_cast assertion failure on empty switch case statements
Fixes #1815
1 parent 5f76859 commit 11bc5b6

3 files changed

Lines changed: 50 additions & 5 deletions

File tree

lib/Differentiator/CladUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ namespace clad {
152152
Stmt* S) {
153153
llvm::SmallVector<Stmt*, 16> block;
154154
block.push_back(S);
155-
CompoundStmt* CS = dyn_cast<CompoundStmt>(initial);
155+
auto* CS = llvm::dyn_cast_or_null<CompoundStmt>(initial);
156156
if (CS)
157157
block.append(CS->body_begin(), CS->body_end());
158-
else
158+
else if (initial)
159159
block.push_back(initial);
160160
auto stmtsRef = clad_compat::makeArrayRef(block.begin(), block.end());
161161
return clad_compat::CompoundStmt_Create(C, stmtsRef /**/CLAD_COMPAT_CLANG15_CompoundStmt_Create_ExtraParam1(CS), noLoc, noLoc);

lib/Differentiator/ReverseModeVisitor.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,9 +2011,12 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
20112011
// We need to check if the last parameter is actually a tracker because
20122012
// custom derivatives currently don't have it.
20132013
if (calleeFnForwPassFD) {
2014-
QualType lastParamType =
2015-
calleeFnForwPassFD->parameters().back()->getType();
2016-
usingRestoreTracker = (utils::GetValueType(lastParamType) == trackerType);
2014+
if (!calleeFnForwPassFD->parameters().empty()) {
2015+
QualType lastParamType =
2016+
calleeFnForwPassFD->parameters().back()->getType();
2017+
usingRestoreTracker =
2018+
(utils::GetValueType(lastParamType) == trackerType);
2019+
}
20172020
}
20182021

20192022
// FIXME: consider moving non-diff analysis to DiffPlanner.

test/Regressions/issue-1815.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -fdump-derived-fn -fsyntax-only -std=c++17 -I%S/../../include %s | FileCheck %s
2+
3+
#include "clad/Differentiator/Differentiator.h"
4+
#include <cstdarg>
5+
6+
typedef enum { a } b;
7+
typedef enum { c, d } e;
8+
e f;
9+
10+
int *g() {
11+
switch (f) {
12+
case c:
13+
break;
14+
}
15+
return nullptr;
16+
}
17+
18+
void h(b, e, char[], char[], int, bool, char, char *, va_list) {
19+
g();
20+
}
21+
22+
char i, o, j;
23+
int k;
24+
25+
void l(float val) {
26+
va_list arg;
27+
h(a, d, &i, &o, k, 0, '\0', &j, arg);
28+
}
29+
30+
double n(double x) {
31+
l(x);
32+
return x * x;
33+
}
34+
35+
void check() {
36+
auto grad_n = clad::gradient(n);
37+
}
38+
39+
// CHECK: void n_grad(double x, double *_d_x)
40+
// CHECK: l(x);
41+
// CHECK: *_d_x += 1 * x;
42+
// CHECK: *_d_x += x * 1;

0 commit comments

Comments
 (0)