From: Bill Wendling Date: Mon, 25 Mar 2013 21:09:49 +0000 (+0000) Subject: Emit an error message instead of crashing when dereferencing an incomplete pointer... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=14df23bd114919abc374b2bcd2b2e16b79936584;p=clang 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 --- 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'}} +}