From: Douglas Gregor Date: Fri, 23 Jan 2009 19:03:35 +0000 (+0000) Subject: Allow subtraction of function pointer types in C, as a GNU extension. Fixes rdar... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0804888d9162cfd422925762c161bd80f80358b9;p=clang Allow subtraction of function pointer types in C, as a GNU extension. Fixes rdar://problem/6520707 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62859 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ab5bd6bd11..6ec4d4a61f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2746,6 +2746,17 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, if (!lpointee->isVoidType()) Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); + } else if (rpointee->isFunctionType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << rex->getType() << rex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + if (!lpointee->isFunctionType()) + Diag(Loc, diag::ext_gnu_ptr_func_arith) + << lex->getType() << lex->getSourceRange(); } else { Diag(Loc, diag::err_typecheck_sub_ptr_object) << rex->getType() << rex->getSourceRange(); diff --git a/test/Sema/pointer-subtract-compat.c b/test/Sema/pointer-subtract-compat.c index 4ed6abf8af..9aebe9cdce 100644 --- a/test/Sema/pointer-subtract-compat.c +++ b/test/Sema/pointer-subtract-compat.c @@ -4,3 +4,8 @@ typedef const char rchar; int a(char* a, rchar* b) { return a-b; } + +// +void f0(void (*fp)(void)) { + int x = fp - fp; // expected-warning{{arithmetic on pointer to function type 'void (*)(void)' is a GNU extension}} +}