[PATCH] D41655: [clang-tidy] New check bugprone-unused-return-value

2018-03-11 Thread Kalle Huttunen via Phabricator via cfe-commits
khuttun added a comment.

Should I close this review?


https://reviews.llvm.org/D41655



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40775: [libcxx] Add underscores to win32 locale headers.

2018-03-11 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added a comment.

ping.


https://reviews.llvm.org/D40775



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40775: [libcxx] Add underscores to win32 locale headers.

2018-03-11 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin updated this revision to Diff 137945.
halyavin added a comment.

update to new revision


https://reviews.llvm.org/D40775

Files:
  src/support/win32/locale_win32.cpp

Index: src/support/win32/locale_win32.cpp
===
--- src/support/win32/locale_win32.cpp
+++ src/support/win32/locale_win32.cpp
@@ -18,9 +18,9 @@
 using std::__libcpp_locale_guard;
 
 // FIXME: base currently unused. Needs manual work to construct the new locale
-locale_t newlocale( int mask, const char * locale, locale_t /*base*/ )
+locale_t newlocale( int __mask, const char * __locale, locale_t /*__base*/ )
 {
-return {_create_locale( LC_ALL, locale ), locale};
+return {_create_locale( LC_ALL, __locale ), __locale};
 }
 
 decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
@@ -34,90 +34,90 @@
 }
 
 
-lconv *localeconv_l( locale_t loc )
+lconv *localeconv_l( locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
+__libcpp_locale_guard __current(__loc);
 return localeconv();
 }
-size_t mbrlen_l( const char *__restrict s, size_t n,
- mbstate_t *__restrict ps, locale_t loc )
+size_t mbrlen_l( const char *__restrict __s, size_t __n,
+ mbstate_t *__restrict __ps, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return mbrlen( s, n, ps );
+__libcpp_locale_guard __current(__loc);
+return mbrlen( __s, __n, __ps );
 }
-size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
-size_t len, mbstate_t *__restrict ps, locale_t loc )
+size_t mbsrtowcs_l( wchar_t *__restrict __dst, const char **__restrict __src,
+size_t __len, mbstate_t *__restrict __ps, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return mbsrtowcs( dst, src, len, ps );
+__libcpp_locale_guard __current(__loc);
+return mbsrtowcs( __dst, __src, __len, __ps );
 }
-size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
-  locale_t loc )
+size_t wcrtomb_l( char *__restrict __s, wchar_t __wc, mbstate_t *__restrict __ps,
+  locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return wcrtomb( s, wc, ps );
+__libcpp_locale_guard __current(__loc);
+return wcrtomb( __s, __wc, __ps );
 }
-size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
-  size_t n, mbstate_t *__restrict ps, locale_t loc )
+size_t mbrtowc_l( wchar_t *__restrict __pwc, const char *__restrict __s,
+  size_t __n, mbstate_t *__restrict __ps, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return mbrtowc( pwc, s, n, ps );
+__libcpp_locale_guard __current(__loc);
+return mbrtowc( __pwc, __s, __n, __ps );
 }
-size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
- size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc )
+size_t mbsnrtowcs_l( wchar_t *__restrict __dst, const char **__restrict __src,
+ size_t __nms, size_t __len, mbstate_t *__restrict __ps, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return mbsnrtowcs( dst, src, nms, len, ps );
+__libcpp_locale_guard __current(__loc);
+return mbsnrtowcs( __dst, __src, __nms, __len, __ps );
 }
-size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
- size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc )
+size_t wcsnrtombs_l( char *__restrict __dst, const wchar_t **__restrict __src,
+ size_t __nwc, size_t __len, mbstate_t *__restrict __ps, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return wcsnrtombs( dst, src, nwc, len, ps );
+__libcpp_locale_guard __current(__loc);
+return wcsnrtombs( __dst, __src, __nwc, __len, __ps );
 }
-wint_t btowc_l( int c, locale_t loc )
+wint_t btowc_l( int __c, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return btowc( c );
+__libcpp_locale_guard __current(__loc);
+return btowc( __c );
 }
-int wctob_l( wint_t c, locale_t loc )
+int wctob_l( wint_t __c, locale_t __loc )
 {
-__libcpp_locale_guard __current(loc);
-return wctob( c );
+__libcpp_locale_guard __current(__loc);
+return wctob( __c );
 }
 
-int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...)
+int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...)
 {
-__libcpp_locale_guard __current(loc);
-va_list ap;
-va_start( ap, format );
-int result = vsnprintf( ret, n, format, ap );
-va_end(ap);
-return result;
+__libcpp_locale_guard __current(__loc);
+va_list __ap;
+va_start(__ap, __format );
+int __result = vsnprintf( __ret, __n, __format, __ap );
+va_end(__ap);
+return __result;
 }
 
-int asprintf_l( char **ret, locale_t loc, const char *format, ... )
+int asprintf_l( char **__ret, locale_t

[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-11 Thread Zinovy Nis via Phabricator via cfe-commits
zinovy.nis marked an inline comment as done.
zinovy.nis added inline comments.



Comment at: test/clang-tidy/bugprone-parent-virtual-call.cpp:125
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's 
method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() override { return BF::virt_1(); }
+};

malcolm.parsons wrote:
> Does this fixit compile?
Thanks for pointing. Hope I fixed this case in the latest patch. Please have a 
look at it.



Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-11 Thread Zinovy Nis via Phabricator via cfe-commits
zinovy.nis updated this revision to Diff 137951.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295

Files:
  clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/bugprone/ParentVirtualCallCheck.cpp
  clang-tidy/bugprone/ParentVirtualCallCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/bugprone-parent-virtual-call.cpp

Index: test/clang-tidy/bugprone-parent-virtual-call.cpp
===
--- /dev/null
+++ test/clang-tidy/bugprone-parent-virtual-call.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+  A() = default;
+  virtual ~A() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+  B() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+  // Test that non-virtual and static methods are not affected by this cherker.
+  int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in anonymous namespaces.
+namespace {
+class BN : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N
+
+class CN : public BN {
+public:
+  int virt_1() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+  int virt_2() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+  AA() = default;
+  virtual ~AA() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+  BB_1() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return AA::virt_1() + 3; }
+  int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+BB_2() = default;
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+  int virt_1() override { return AA::virt_1() + 3; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'AA::virt_1' is a grand-parent's method, not parent's. Did you mean 'BB_1' or 'BB_2'? [bugprone-parent-virtual-call]
+  // No fix available due to multiple choice of parent class.
+};
+
+// Test templated classes.
+template  class BF : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF {
+public:
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() override { return BF::virt_1(); }
+};
+
+// Test b

[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-11 Thread Zinovy Nis via Phabricator via cfe-commits
zinovy.nis updated this revision to Diff 137952.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295

Files:
  clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/bugprone/ParentVirtualCallCheck.cpp
  clang-tidy/bugprone/ParentVirtualCallCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/bugprone-parent-virtual-call.cpp

Index: test/clang-tidy/bugprone-parent-virtual-call.cpp
===
--- /dev/null
+++ test/clang-tidy/bugprone-parent-virtual-call.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+  A() = default;
+  virtual ~A() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+  B() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+  // Test that non-virtual and static methods are not affected by this cherker.
+  int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in anonymous namespaces.
+namespace {
+class BN : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N
+
+class CN : public BN {
+public:
+  int virt_1() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+  int virt_2() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+  AA() = default;
+  virtual ~AA() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+  BB_1() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return AA::virt_1() + 3; }
+  int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+BB_2() = default;
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+  int virt_1() override { return AA::virt_1() + 3; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'AA::virt_1' is a grand-parent's method, not parent's. Did you mean 'BB_1' or 'BB_2'? [bugprone-parent-virtual-call]
+  // No fix available due to multiple choice of parent class.
+};
+
+// Test templated classes.
+template  class BF : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF {
+public:
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() override { return BF::virt_1(); }
+};
+
+// Test b

[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-11 Thread Zinovy Nis via Phabricator via cfe-commits
zinovy.nis updated this revision to Diff 137953.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295

Files:
  clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/bugprone/ParentVirtualCallCheck.cpp
  clang-tidy/bugprone/ParentVirtualCallCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/bugprone-parent-virtual-call.cpp

Index: test/clang-tidy/bugprone-parent-virtual-call.cpp
===
--- /dev/null
+++ test/clang-tidy/bugprone-parent-virtual-call.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+  A() = default;
+  virtual ~A() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+  B() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+  // Test that non-virtual and static methods are not affected by this cherker.
+  int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in anonymous namespaces.
+namespace {
+class BN : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N
+
+class CN : public BN {
+public:
+  int virt_1() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+  int virt_2() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BN'?
+  // CHECK-FIXES:  int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+  AA() = default;
+  virtual ~AA() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+  BB_1() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return AA::virt_1() + 3; }
+  int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+BB_2() = default;
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+  int virt_1() override { return AA::virt_1() + 3; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'AA::virt_1' is a grand-parent's method, not parent's. Did you mean 'BB_1' or 'BB_2'? [bugprone-parent-virtual-call]
+  // No fix available due to multiple choice of parent class.
+};
+
+// Test templated classes.
+template  class BF : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF {
+public:
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() override { return BF::virt_1(); }
+};
+
+// Test b

[PATCH] D44371: [Driver] Update the comment about incompatible sanitizers

2018-03-11 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added a reviewer: thakis.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D44371

Files:
  clang/lib/Driver/SanitizerArgs.cpp


Index: clang/lib/Driver/SanitizerArgs.cpp
===
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -348,7 +348,8 @@
   // Enable toolchain specific default sanitizers if not explicitly disabled.
   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
 
-  // Disable default sanitizers that are incompatible with the default ones.
+  // Disable default sanitizers that are incompatible with explicitly requested
+  // ones.
   for (auto G : IncompatibleGroups) {
 SanitizerMask Group = G.first;
 if ((Default & Group) && (Kinds & G.second))


Index: clang/lib/Driver/SanitizerArgs.cpp
===
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -348,7 +348,8 @@
   // Enable toolchain specific default sanitizers if not explicitly disabled.
   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
 
-  // Disable default sanitizers that are incompatible with the default ones.
+  // Disable default sanitizers that are incompatible with explicitly requested
+  // ones.
   for (auto G : IncompatibleGroups) {
 SanitizerMask Group = G.first;
 if ((Default & Group) && (Kinds & G.second))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-11 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tidy/bugprone/ParentVirtualCallCheck.cpp:47
+const CXXRecordDecl *ThisClass) {
+
+  assert(GrandParent != nullptr);

Please remove empty line.



Comment at: clang-tidy/bugprone/ParentVirtualCallCheck.cpp:116
+
+  if (IsParentOf(CastToType, ThisType)) {
+return;

No need for brackets.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r327249 - [Driver] Update the comment about incompatible sanitizers

2018-03-11 Thread Petr Hosek via cfe-commits
Author: phosek
Date: Sun Mar 11 17:23:37 2018
New Revision: 327249

URL: http://llvm.org/viewvc/llvm-project?rev=327249&view=rev
Log:
[Driver] Update the comment about incompatible sanitizers

Differential Revision: https://reviews.llvm.org/D44371

Modified:
cfe/trunk/lib/Driver/SanitizerArgs.cpp

Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=327249&r1=327248&r2=327249&view=diff
==
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Sun Mar 11 17:23:37 2018
@@ -348,7 +348,8 @@ SanitizerArgs::SanitizerArgs(const ToolC
   // Enable toolchain specific default sanitizers if not explicitly disabled.
   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
 
-  // Disable default sanitizers that are incompatible with the default ones.
+  // Disable default sanitizers that are incompatible with explicitly requested
+  // ones.
   for (auto G : IncompatibleGroups) {
 SanitizerMask Group = G.first;
 if ((Default & Group) && (Kinds & G.second))


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44371: [Driver] Update the comment about incompatible sanitizers

2018-03-11 Thread Petr Hosek via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL327249: [Driver] Update the comment about incompatible 
sanitizers (authored by phosek, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D44371?vs=137957&id=137960#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D44371

Files:
  cfe/trunk/lib/Driver/SanitizerArgs.cpp


Index: cfe/trunk/lib/Driver/SanitizerArgs.cpp
===
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp
@@ -348,7 +348,8 @@
   // Enable toolchain specific default sanitizers if not explicitly disabled.
   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
 
-  // Disable default sanitizers that are incompatible with the default ones.
+  // Disable default sanitizers that are incompatible with explicitly requested
+  // ones.
   for (auto G : IncompatibleGroups) {
 SanitizerMask Group = G.first;
 if ((Default & Group) && (Kinds & G.second))


Index: cfe/trunk/lib/Driver/SanitizerArgs.cpp
===
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp
@@ -348,7 +348,8 @@
   // Enable toolchain specific default sanitizers if not explicitly disabled.
   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
 
-  // Disable default sanitizers that are incompatible with the default ones.
+  // Disable default sanitizers that are incompatible with explicitly requested
+  // ones.
   for (auto G : IncompatibleGroups) {
 SanitizerMask Group = G.first;
 if ((Default & Group) && (Kinds & G.second))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43248: [Attr] Fix parameter indexing for attributes

2018-03-11 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny updated this revision to Diff 137964.
jdenny added a comment.

This commit was reverted by r326862 due to:

https://bugs.llvm.org/show_bug.cgi?id=36620

This revision includes a new test case and a fix.

While the difference from the last revision is small, it's not trivial, so 
another review is probably worthwhile.  The main difference is two new  
ParamIdx member functions: serialize and deserialize.   In 
ClangAttrEmitter.cpp, these functions enable significant simplifications and 
facilitate the bug fix.


https://reviews.llvm.org/D43248

Files:
  include/clang/AST/Attr.h
  include/clang/Basic/Attr.td
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGCall.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
  test/CodeGenCXX/alloc-size.cpp
  test/Frontend/ast-attr.cpp
  test/Misc/ast-dump-attr.cpp
  test/Sema/attr-ownership.cpp
  test/Sema/attr-print.cpp
  test/Sema/error-type-safety.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -104,6 +104,7 @@
 .Case("Expr *", "Record.readExpr()")
 .Case("IdentifierInfo *", "Record.getIdentifierInfo()")
 .Case("StringRef", "Record.readString()")
+.Case("ParamIdx", "ParamIdx::deserialize(Record.readInt())")
 .Default("Record.readInt()");
 }
 
@@ -122,6 +123,7 @@
 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
 .Case("IdentifierInfo *", "AddIdentifierRef(" + std::string(name) + ");\n")
 .Case("StringRef", "AddString(" + std::string(name) + ");\n")
+.Case("ParamIdx", "push_back(" + std::string(name) + ".serialize());\n")
 .Default("push_back(" + std::string(name) + ");\n");
 }
 
@@ -302,9 +304,8 @@
 std::string getIsOmitted() const override {
   if (type == "IdentifierInfo *")
 return "!get" + getUpperName().str() + "()";
-  // FIXME: Do this declaratively in Attr.td.
-  if (getAttrName() == "AllocSize")
-return "0 == get" + getUpperName().str() + "()";
+  if (type == "ParamIdx")
+return "!get" + getUpperName().str() + "().isValid()";
   return "false";
 }
 
@@ -319,6 +320,8 @@
<< "()->getName() : \"\") << \"";
   else if (type == "TypeSourceInfo *")
 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
+  else if (type == "ParamIdx")
+OS << "\" << get" << getUpperName() << "().getSourceIndex() << \"";
   else
 OS << "\" << get" << getUpperName() << "() << \"";
 }
@@ -341,6 +344,11 @@
<< getUpperName() << "\";\n";
   } else if (type == "int" || type == "unsigned") {
 OS << "OS << \" \" << SA->get" << getUpperName() << "();\n";
+  } else if (type == "ParamIdx") {
+if (isOptional())
+  OS << "if (SA->get" << getUpperName() << "().isValid())\n  ";
+OS << "OS << \" \" << SA->get" << getUpperName()
+   << "().getSourceIndex();\n";
   } else {
 llvm_unreachable("Unknown SimpleArgument type!");
   }
@@ -618,6 +626,10 @@
 virtual void writeValueImpl(raw_ostream &OS) const {
   OS << "OS << Val;\n";
 }
+// Assumed to receive a parameter: raw_ostream OS.
+virtual void writeDumpImpl(raw_ostream &OS) const {
+  OS << "  OS << \" \" << Val;\n";
+}
 
   public:
 VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
@@ -744,7 +756,22 @@
 
 void writeDump(raw_ostream &OS) const override {
   OS << "for (const auto &Val : SA->" << RangeName << "())\n";
-  OS << "  OS << \" \" << Val;\n";
+  writeDumpImpl(OS);
+}
+  };
+
+  class VariadicParamIdxArgument : public VariadicArgument {
+  public:
+VariadicParamIdxArgument(const Record &Arg, StringRef Attr)
+: VariadicArgument(Arg, Attr, "ParamIdx") {}
+
+  public:
+void writeValueImpl(raw_ostream &OS) const override {
+  OS << "OS << Val.getSourceIndex();\n";
+}
+
+void writeDumpImpl(raw_ostream &OS) const override {
+  OS << "  OS << \" \" << Val.getSourceIndex();\n";
 }
   };
 
@@ -1247,6 +1274,10 @@
 Ptr = llvm::make_unique(Arg, Attr);
   else if (ArgName == "VariadicExprArgument")
 Ptr = llvm::make_unique(Arg, Attr);
+  else if (ArgName == "VariadicParamIdxArgument")
+Ptr = llvm::make_unique(Arg, Attr);
+  else if (ArgName == "ParamIdxArgument")
+Ptr = llvm::make_unique(Arg, Attr, "ParamIdx");
   else if (ArgName == "VersionArgument")
 Ptr = llvm::make_unique(Arg, Attr);
 
Index: test/Sema/error-type-safety.cpp
===
--- test/Sema/error-type-safety.cpp
+++ test/Sema/error-type-safety.cpp
@@ -3,21 +3,50 @@
 #define INT_TAG 42

[PATCH] D44362: [clang] Change std::sort to llvm::sort in response to r327219

2018-03-11 Thread Mandeep Singh Grang via Phabricator via cfe-commits
mgrang updated this revision to Diff 137966.
mgrang added a comment.

Fixed indentation.


Repository:
  rC Clang

https://reviews.llvm.org/D44362

Files:
  include/clang/Basic/Attr.td
  include/clang/Serialization/ContinuousRangeMap.h
  lib/AST/ASTContext.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/VTableBuilder.cpp
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/Analysis/LiveVariables.cpp
  lib/Basic/VirtualFileSystem.cpp
  lib/CodeGen/CGVTables.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/Driver.cpp
  lib/Format/FormatTokenLexer.cpp
  lib/Format/WhitespaceManager.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Sema/AnalysisBasedWarnings.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/CheckerRegistry.cpp
  lib/Tooling/ASTDiff/ASTDiff.cpp
  lib/Tooling/Core/Replacement.cpp
  tools/diagtool/DiagTool.cpp
  tools/libclang/CIndex.cpp
  unittests/Basic/VirtualFileSystemTest.cpp
  utils/TableGen/ClangAttrEmitter.cpp
  utils/TableGen/ClangDiagnosticsEmitter.cpp
  utils/TableGen/ClangOptionDocEmitter.cpp
  utils/TableGen/NeonEmitter.cpp

Index: utils/TableGen/NeonEmitter.cpp
===
--- utils/TableGen/NeonEmitter.cpp
+++ utils/TableGen/NeonEmitter.cpp
@@ -2007,7 +2007,7 @@
 }
   }
 
-  std::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+  llvm::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
   NewTypeSpecs.erase(std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end()),
 		 NewTypeSpecs.end());
   auto &Entry = IntrinsicMap[Name];
Index: utils/TableGen/ClangOptionDocEmitter.cpp
===
--- utils/TableGen/ClangOptionDocEmitter.cpp
+++ utils/TableGen/ClangOptionDocEmitter.cpp
@@ -111,25 +111,25 @@
 
   auto DocumentationForOption = [&](Record *R) -> DocumentedOption {
 auto &A = Aliases[R];
-std::sort(A.begin(), A.end(), CompareByName);
+llvm::sort(A.begin(), A.end(), CompareByName);
 return {R, std::move(A)};
   };
 
   std::function DocumentationForGroup =
   [&](Record *R) -> Documentation {
 Documentation D;
 
 auto &Groups = GroupsInGroup[R];
-std::sort(Groups.begin(), Groups.end(), CompareByLocation);
+llvm::sort(Groups.begin(), Groups.end(), CompareByLocation);
 for (Record *G : Groups) {
   D.Groups.emplace_back();
   D.Groups.back().Group = G;
   Documentation &Base = D.Groups.back();
   Base = DocumentationForGroup(G);
 }
 
 auto &Options = OptionsInGroup[R];
-std::sort(Options.begin(), Options.end(), CompareByName);
+llvm::sort(Options.begin(), Options.end(), CompareByName);
 for (Record *O : Options)
   D.Options.push_back(DocumentationForOption(O));
 
Index: utils/TableGen/ClangDiagnosticsEmitter.cpp
===
--- utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -207,9 +207,9 @@
   E = SortedGroups.end();
I != E; ++I) {
 MutableArrayRef GroupDiags = (*I)->DiagsInGroup;
-std::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
+llvm::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
   }
-  std::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
+  llvm::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
 
   // Warn about the same group being used anonymously in multiple places.
   for (SmallVectorImpl::const_iterator I = SortedGroups.begin(),
@@ -863,9 +863,10 @@
 Index.push_back(RecordIndexElement(R));
   }
 
-  std::sort(Index.begin(), Index.end(),
-[](const RecordIndexElement &Lhs,
-   const RecordIndexElement &Rhs) { return Lhs.Name < Rhs.Name; });
+  llvm::sort(Index.begin(), Index.end(),
+ [](const RecordIndexElement &Lhs, const RecordIndexElement &Rhs) {
+   return Lhs.Name < Rhs.Name;
+});
 
   for (unsigned i = 0, e = Index.size(); i != e; ++i) {
 const RecordIndexElement &R = Index[i];
@@ -1212,7 +1213,7 @@
   Records.getAllDerivedDefinitions("Diagnostic");
   std::vector DiagGroups =
   Records.getAllDerivedDefinitions("DiagGroup");
-  std::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
+  llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
 
   DiagGroupParentMap DGParentMap(Records);
 
@@ -1231,10 +1232,10 @@
   DiagsInPedanticSet.end());
 RecordVec GroupsInPedantic(GroupsInPedanticSet.begin(),
GroupsInPedanticSe

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-11 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 7 inline comments as done.
lichray added a comment.
Herald added a subscriber: christof.

Pending patch update due to poor network.




Comment at: include/charconv:90
+
+enum class _LIBCPP_ENUM_VIS chars_format
+{

EricWF wrote:
> enum types should have their underlying integer type explicitly specified. 
> Otherwise their size and ABI can break when users specify `-short-enums`
The standard requires `enum class` to default to `int`; IIUC `enum class` is 
not affected by `-fshort-enums`.



Comment at: include/support/itoa/itoa.h:1
+// -*- C++ -*-
+//===- support/itoa/itoa.h 
===//

EricWF wrote:
> I would rather not introduce another header for this. I think it should go 
> directly in the `charconv` header.
We may have separated floating point headers coming as well...



Comment at: include/support/itoa/itoa.h:47
+
+static constexpr uint32_t __pow10_32[] = {
+UINT32_C(0),  UINT32_C(10),   UINT32_C(100),

EricWF wrote:
> I suspect we can use `__pow10_64` in the 32 bit case as well to avoid 
> emitting another static global.
I have functions returning them as array references.



Comment at: include/support/itoa/itoa.h:54
+
+#if __has_builtin(__builtin_clzll)
+

EricWF wrote:
> Use `__clz` from ``. You can assume we always have that.
Factor `__clz` out of `algorithm` may be too much for this review.  I would 
like to see a subsequent patch to take care of all the related portability 
fixes.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44189: [RISCV] Verify the input value of -march=

2018-03-11 Thread Kito Cheng via Phabricator via cfe-commits
kito-cheng updated this revision to Diff 137970.
kito-cheng added a comment.

Add test cases for the correct inputs.


https://reviews.llvm.org/D44189

Files:
  lib/Driver/ToolChains/Arch/RISCV.cpp
  test/Driver/riscv-arch.c

Index: test/Driver/riscv-arch.c
===
--- /dev/null
+++ test/Driver/riscv-arch.c
@@ -0,0 +1,77 @@
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32im -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ima -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imaf -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imafd -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ic -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imac -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imafc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imafdc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ia -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iaf -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iafd -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iac -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iafc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iafdc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32g -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv32-unknown-elf -march=rv32gc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64i -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64im -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64ima -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imaf -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imafd -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64ic -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imac -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imafc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64imafdc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64ia -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64iaf -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64iafd -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64iac -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64iafc -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64iafdc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64g -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target riscv64-unknown-elf -march=rv64gc -### %s -fsyntax-only 2>&1 | FileCheck %s
+
+// CHECK-NOT: error: invalid arch name '
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32 -### %s -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32 %s
+// RV32: error: invalid arch name 'rv32'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32m -### %s -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32M %s
+// RV32M: error: invalid arch name 'rv32m'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32id -### %s -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32ID %s
+// RV32ID: error: invalid arch name 'rv32id'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32l -### %s -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32L %s
+// RV32L: error: invalid arch name 'rv32l'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32imadf -### %s -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32IMADF %s
+// RV32IMADF: error: invalid arch name 'rv32imadf'
+
+// RUN: %clang -target riscv64-unknown-elf -march=rv64 -### %