Index: Sema/SemaExpr.cpp =================================================================== --- Sema/SemaExpr.cpp (revision 46872) +++ Sema/SemaExpr.cpp (working copy) @@ -1329,10 +1343,40 @@ if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) return compType; - if (lex->getType()->isPointerType() && rex->getType()->isIntegerType()) - return lex->getType(); - if (lex->getType()->isIntegerType() && rex->getType()->isPointerType()) - return rex->getType(); + if (const PointerType* PTy = lex->getType()->getAsPointerType()) { + if (rex->getType()->isIntegerType()) { + // Check for arithmetic on pointers to incomplete types + if (!PTy->getPointeeType()->isObjectType()) { + if (PTy->getPointeeType()->isVoidType()) { + Diag(loc, diag::ext_gnu_void_ptr, + lex->getSourceRange(), rex->getSourceRange()); + } else { + Diag(loc, diag::err_typecheck_arithmetic_incomplete_type, + lex->getType().getAsString(), lex->getSourceRange()); + return QualType(); + } + } + return lex->getType(); + } + } + + if (const PointerType* PTy = rex->getType()->getAsPointerType()) { + if (lex->getType()->isIntegerType()) { + // Check for arithmetic on pointers to incomplete types + if (!PTy->getPointeeType()->isObjectType()) { + if (PTy->getPointeeType()->isVoidType()) { + Diag(loc, diag::ext_gnu_void_ptr, + rex->getSourceRange(), lex->getSourceRange()); + } else { + Diag(loc, diag::err_typecheck_arithmetic_incomplete_type, + rex->getType().getAsString(), rex->getSourceRange()); + return QualType(); + } + } + return rex->getType(); + } + } + return InvalidOperands(loc, lex, rex); }