]> granicus.if.org Git - clang/commitdiff
Sema: Semantically check _Atomic-qualified pointers
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 12 Feb 2015 21:07:34 +0000 (21:07 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 12 Feb 2015 21:07:34 +0000 (21:07 +0000)
This fixes PR22568.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228959 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/Sema/pointer-addition.c

index 2b4c639dcd8f112d189d6aa34a9fd0c305d3c2a3..a9ea72577ab53cd524ff5c33e464046f367a59da 100644 (file)
@@ -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<AtomicType>())
+    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<AtomicType>())
+    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;
index 21ce63b4381fc35b2dfcc9a872d1662913034c7d..667fe9a68c1537953f6ba6e7bdb04af5118ce515 100644 (file)
@@ -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}}
 }