diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-01-23 00:36:41 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-01-23 00:36:41 +0000 |
| commit | f6cd928bf4576811f1aa6ecae84be5b2e048d14c (patch) | |
| tree | e913128860f943240147ffc16b27f42c14037b8e /clang/lib | |
| parent | 706d40e66235dafb85557ade0bb6c2209111d878 (diff) | |
| download | bcm5719-llvm-f6cd928bf4576811f1aa6ecae84be5b2e048d14c.tar.gz bcm5719-llvm-f6cd928bf4576811f1aa6ecae84be5b2e048d14c.zip | |
Support arithmetic on pointer-to-function types as a GNU
extension. Addresses clang PR/3371.
llvm-svn: 62823
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8cf153e673d..ab5bd6bd119 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2656,12 +2656,25 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 // Check for arithmetic on pointers to incomplete types if (!PTy->getPointeeType()->isObjectType()) { if (PTy->getPointeeType()->isVoidType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_void_type) + << lex->getSourceRange() << rex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to void Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); } else if (PTy->getPointeeType()->isFunctionType()) { - Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << lex->getType() << lex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + Diag(Loc, diag::ext_gnu_ptr_func_arith) << lex->getType() << lex->getSourceRange(); - return QualType(); } else { DiagnoseIncompleteType(Loc, PTy->getPointeeType(), diag::err_typecheck_arithmetic_incomplete_type, @@ -2701,6 +2714,16 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, if (lpointee->isVoidType()) { Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); + } else if (lpointee->isFunctionType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << lex->getType() << lex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + Diag(Loc, diag::ext_gnu_ptr_func_arith) + << lex->getType() << lex->getSourceRange(); } else { Diag(Loc, diag::err_typecheck_sub_ptr_object) << lex->getType() << lex->getSourceRange(); @@ -3174,10 +3197,22 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc, if (PT->getPointeeType()->isObjectType()) { // Pointer to object is ok! } else if (PT->getPointeeType()->isVoidType()) { - // Pointer to void is extension. + if (getLangOptions().CPlusPlus) { + Diag(OpLoc, diag::err_typecheck_pointer_arith_void_type) + << Op->getSourceRange(); + return QualType(); + } + + // Pointer to void is a GNU extension in C. Diag(OpLoc, diag::ext_gnu_void_ptr) << Op->getSourceRange(); } else if (PT->getPointeeType()->isFunctionType()) { - Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type) + if (getLangOptions().CPlusPlus) { + Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type) + << Op->getType() << Op->getSourceRange(); + return QualType(); + } + + Diag(OpLoc, diag::ext_gnu_ptr_func_arith) << ResType << Op->getSourceRange(); return QualType(); } else { |

