Skip to content

Commit 26bb776

Browse files
committed
[Clang] Fix crash for incompatible types in inline assembly
1 parent 7787328 commit 26bb776

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

clang/lib/Sema/SemaStmtAsm.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,19 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
664664
SmallerValueMentioned |= OutSize < InSize;
665665
}
666666

667+
// If the input is in an integer register while the output is floating point,
668+
// there is no way we can extend and we must reject it.
669+
bool FPExtendFromInt = false;
670+
if (InputDomain != AD_Float && OutputDomain == AD_Float) {
671+
FPExtendFromInt = true;
672+
}
673+
667674
// If the smaller value wasn't mentioned in the asm string, and if the
668675
// output was a register, just extend the shorter one to the size of the
669676
// larger one.
670-
if (!SmallerValueMentioned && InputDomain != AD_Other &&
677+
if (!SmallerValueMentioned && !FPExtendFromInt && InputDomain != AD_Other &&
671678
OutputConstraintInfos[TiedTo].allowsRegister()) {
679+
672680
// FIXME: GCC supports the OutSize to be 128 at maximum. Currently codegen
673681
// crash when the size larger than the register size. So we limit it here.
674682
if (OutTy->isStructureType() &&

clang/test/Sema/PR119098.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify
2+
3+
// expected-warning@+2 {{incompatible redeclaration of library function 'fabs'}}
4+
// expected-note@+1 {{'fabs' is a builtin with type 'double (double)'}}
5+
extern __inline double
6+
fabs (char __x)
7+
{
8+
register double __value;
9+
__asm __volatile__
10+
("fabs"
11+
: "=t" (__value) : "0" (__x)); // expected-error {{unsupported inline asm: input with type 'char' matching output with type 'double'}}
12+
return __value;
13+
}
14+
int
15+
foo ()
16+
{
17+
int i, j, k;
18+
double x = 0, y = ((i == j) ? 1 : 0);
19+
for (i = 0; i < 10; i++)
20+
;
21+
fabs (x - y);
22+
return 0;
23+
}

0 commit comments

Comments
 (0)