From: David Majnemer Date: Thu, 12 Feb 2015 21:07:34 +0000 (+0000) Subject: Sema: Semantically check _Atomic-qualified pointers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a3e2d8e9818e326383b8164f726b480f4409018;p=clang Sema: Semantically check _Atomic-qualified pointers This fixes PR22568. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228959 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2b4c639dcd..a9ea72577a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7334,9 +7334,12 @@ static void diagnoseArithmeticOnFunctionPointer(Sema &S, SourceLocation Loc, /// \returns True if pointer has incomplete type static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc, Expr *Operand) { - assert(Operand->getType()->isAnyPointerType() && - !Operand->getType()->isDependentType()); - QualType PointeeTy = Operand->getType()->getPointeeType(); + QualType ResType = Operand->getType(); + if (const AtomicType *ResAtomicType = ResType->getAs()) + ResType = ResAtomicType->getValueType(); + + assert(ResType->isAnyPointerType() && !ResType->isDependentType()); + QualType PointeeTy = ResType->getPointeeType(); return S.RequireCompleteType(Loc, PointeeTy, diag::err_typecheck_arithmetic_incomplete_type, PointeeTy, Operand->getSourceRange()); @@ -7352,9 +7355,13 @@ static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc, /// \returns True when the operand is valid to use (even if as an extension). static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc, Expr *Operand) { - if (!Operand->getType()->isAnyPointerType()) return true; + QualType ResType = Operand->getType(); + if (const AtomicType *ResAtomicType = ResType->getAs()) + ResType = ResAtomicType->getValueType(); + + if (!ResType->isAnyPointerType()) return true; - QualType PointeeTy = Operand->getType()->getPointeeType(); + QualType PointeeTy = ResType->getPointeeType(); if (PointeeTy->isVoidType()) { diagnoseArithmeticOnVoidPointer(S, Loc, Operand); return !S.getLangOpts().CPlusPlus; diff --git a/test/Sema/pointer-addition.c b/test/Sema/pointer-addition.c index 21ce63b438..667fe9a68c 100644 --- a/test/Sema/pointer-addition.c +++ b/test/Sema/pointer-addition.c @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic +// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11 -typedef struct S S; // expected-note 3 {{forward declaration of 'struct S'}} +typedef struct S S; // expected-note 4 {{forward declaration of 'struct S'}} +extern _Atomic(S*) e; void a(S* b, void* c) { void (*fp)(int) = 0; b++; // expected-error {{arithmetic on a pointer to an incomplete type}} @@ -18,4 +19,5 @@ void a(S* b, void* c) { d--; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} d -= 1; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} (void)(1 + d); // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} + e++; // expected-error {{arithmetic on a pointer to an incomplete type}} }