diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -15171,8 +15171,12 @@ const CallExpr *E) { SmallVector Ops; - for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) - Ops.push_back(EmitScalarExpr(E->getArg(i))); + for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { + if (E->getArg(i)->getType()->isArrayType()) + Ops.push_back(EmitArrayToPointerDecay(E->getArg(i)).getPointer()); + else + Ops.push_back(EmitScalarExpr(E->getArg(i))); + } Intrinsic::ID ID = Intrinsic::not_intrinsic; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -7553,11 +7553,11 @@ StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType(); // The only case where the argument type and expected type are allowed to - // mismatch is if the argument type is a non-void pointer and expected type - // is a void pointer. + // mismatch is if the argument type is a non-void pointer (or array) and + // expected type is a void pointer. if (StrippedRVType != ExpectedType) if (!(ExpectedType->isVoidPointerType() && - StrippedRVType->isPointerType())) + (StrippedRVType->isPointerType() || StrippedRVType->isArrayType()))) return Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible) << PassedType << ExpectedType << 1 << 0 << 0; diff --git a/clang/test/Sema/ppc-pair-mma-types.c b/clang/test/Sema/ppc-pair-mma-types.c --- a/clang/test/Sema/ppc-pair-mma-types.c +++ b/clang/test/Sema/ppc-pair-mma-types.c @@ -339,20 +339,20 @@ void testRestrictQualifiedPointer1(int *__restrict acc) { vector float arr[4]; - __builtin_mma_disassemble_acc((void *)arr, acc); // expected-error {{passing 'int *restrict' to parameter of incompatible type '__vector_quad *'}} + __builtin_mma_disassemble_acc(arr, acc); // expected-error {{passing 'int *restrict' to parameter of incompatible type '__vector_quad *'}} } void testRestrictQualifiedPointer2(__vector_quad *__restrict acc) { vector float arr[4]; - __builtin_mma_disassemble_acc((void *)arr, acc); + __builtin_mma_disassemble_acc(arr, acc); } void testVolatileQualifiedPointer1(int *__volatile acc) { vector float arr[4]; - __builtin_mma_disassemble_acc((void *)arr, acc); // expected-error {{passing 'int *volatile' to parameter of incompatible type '__vector_quad *'}} + __builtin_mma_disassemble_acc(arr, acc); // expected-error {{passing 'int *volatile' to parameter of incompatible type '__vector_quad *'}} } void testVolatileQualifiedPointer2(__vector_quad *__volatile acc) { vector float arr[4]; - __builtin_mma_disassemble_acc((void *)arr, acc); + __builtin_mma_disassemble_acc(arr, acc); }