From 14df23bd114919abc374b2bcd2b2e16b79936584 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 25 Mar 2013 21:09:49 +0000 Subject: [PATCH] Emit an error message instead of crashing when dereferencing an incomplete pointer type. If the ASM statement is dereferencing an incomplete pointer type, issue an error instead of crashing. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177915 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaStmtAsm.cpp | 22 +++++++++++++++------- test/CodeGen/x86_32-inline-asm.c | 7 ------- test/Sema/asm.c | 7 +++++++ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1bc3dab93e..b93dc3294f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4057,6 +4057,8 @@ def err_subscript_function_type : Error< "subscript of pointer to function type %0">; def err_subscript_incomplete_type : Error< "subscript of pointer to incomplete type %0">; +def err_dereference_incomplete_type : Error< + "dereference of pointer to incomplete type %0">; def ext_gnu_subscript_void_type : Extension< "subscript of a pointer to void is a GNU extension">, InGroup; def err_typecheck_member_reference_struct_union : Error< diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 95964e20a7..fc693e6cd7 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -124,11 +124,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // Check that the output exprs are valid lvalues. Expr *OutputExpr = Exprs[i]; - if (CheckAsmLValue(OutputExpr, *this)) { + if (CheckAsmLValue(OutputExpr, *this)) return StmtError(Diag(OutputExpr->getLocStart(), - diag::err_asm_invalid_lvalue_in_output) - << OutputExpr->getSourceRange()); - } + diag::err_asm_invalid_lvalue_in_output) + << OutputExpr->getSourceRange()); + + if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(), 0)) + return StmtError(Diag(OutputExpr->getLocStart(), + diag::err_dereference_incomplete_type) + << Exprs[i]->getType()); OutputConstraintInfos.push_back(Info); } @@ -181,11 +185,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, InputConstraintInfos.push_back(Info); const Type *Ty = Exprs[i]->getType().getTypePtr(); - if (Ty->isDependentType() || - RequireCompleteType(InputExpr->getLocStart(), - Exprs[i]->getType(), 0)) + if (Ty->isDependentType()) continue; + if (!Ty->isVoidType() || !Info.allowsMemory()) + if (RequireCompleteType(InputExpr->getLocStart(), Exprs[i]->getType(), 0)) + return StmtError(Diag(InputExpr->getLocStart(), + diag::err_dereference_incomplete_type) + << Exprs[i]->getType()); + unsigned Size = Context.getTypeSize(Ty); if (!Context.getTargetInfo().validateInputSize(Literal->getString(), Size)) diff --git a/test/CodeGen/x86_32-inline-asm.c b/test/CodeGen/x86_32-inline-asm.c index aebc4e4a06..473f78ebca 100644 --- a/test/CodeGen/x86_32-inline-asm.c +++ b/test/CodeGen/x86_32-inline-asm.c @@ -22,10 +22,3 @@ int func1() { unsigned int port; __asm__ volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); // No error expected. } - -struct S; -void func2(struct S *s) { - __asm__ volatile("" - : - : "a" (*s)); -} diff --git a/test/Sema/asm.c b/test/Sema/asm.c index 155d736b99..b901e378cf 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -123,3 +123,10 @@ void test13(void) { void *esp; __asm__ volatile ("mov %%esp, %o" : "=r"(esp) : : ); // expected-error {{invalid % escape in inline assembly string}} } + +// +struct S; +void test14(struct S *s) { + __asm("": : "a"(*s)); // expected-error {{dereference of pointer to incomplete type 'struct S'}} + __asm("": "=a" (*s) :); // expected-error {{dereference of pointer to incomplete type 'struct S'}} +} -- 2.49.0