Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1663,12 +1663,18 @@ if (T.isNull()) return QualType(); + QualType OriginalType = T; + // Enforce C99 6.7.3p2: "Types other than pointer types derived from // object or incomplete types shall not be restrict-qualified." if (Qs.hasRestrict()) { unsigned DiagID = 0; QualType ProblemTy; + // Handle code like "int * _Atomic restrict p". + if (const AtomicType *AtomicT = T->getAs()) + T = AtomicT->getValueType(); + if (T->isAnyPointerType() || T->isReferenceType() || T->isMemberPointerType()) { QualType EltTy; @@ -1696,7 +1702,7 @@ } } - return Context.getQualifiedType(T, Qs); + return Context.getQualifiedType(OriginalType, Qs); } QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, Index: test/Misc/ast-dump-restrict-atomic.c =================================================================== --- test/Misc/ast-dump-restrict-atomic.c +++ test/Misc/ast-dump-restrict-atomic.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c11 -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=c11 -verify %s +// expected-no-diagnostics + +int * _Atomic restrict a; +int * restrict _Atomic b; +int _Atomic * restrict c; +volatile _Atomic int * restrict _Atomic const * restrict d; + +// CHECK: a '__restrict _Atomic(int *)' +// CHECK: b '__restrict _Atomic(int *)' +// CHECK: c '_Atomic(int) *__restrict' +// CHECK: d 'const __restrict _Atomic(volatile _Atomic(int) *) *__restrict'