diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9972,6 +9972,11 @@ return UnsignedLongLongTy; case BuiltinType::Int128: return UnsignedInt128Ty; + // wchar_t is special. It is either signed or not, but when it's signed, + // there's no matching "unsigned wchar_t". Therefore we return the unsigned + // version of it's underlying type instead. + case BuiltinType::WChar_S: + return getUnsignedWCharType(); case BuiltinType::ShortAccum: return UnsignedShortAccumTy; diff --git a/clang/test/SemaCXX/wchar_t.cpp b/clang/test/SemaCXX/wchar_t.cpp --- a/clang/test/SemaCXX/wchar_t.cpp +++ b/clang/test/SemaCXX/wchar_t.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -Wno-signed-unsigned-wchar -verify=allow-signed %s +// RUN: %clang_cc1 -fsyntax-only -Wno-signed-unsigned-wchar -verify=allow-signed -DSKIP_ERROR_TESTS %s // allow-signed-no-diagnostics wchar_t x; @@ -32,3 +32,10 @@ // rdar://8040728 wchar_t in[] = L"\x434" "\x434"; // No warning +#ifndef SKIP_ERROR_TESTS +// Verify that we do not crash when assigning wchar_t* to another pointer type. +void assignment(wchar_t *x) { + char *y; + y = x; // expected-error {{incompatible pointer types assigning to 'char *' from 'wchar_t *'}} +} +#endif