[PATCH] D44580: Sema: allow comparison between blocks & block-compatible objc types

2018-03-17 Thread David Chisnall via Phabricator via cfe-commits
theraven added a comment.

We seem to be missing tests for the assignment part of this patch.




Comment at: lib/Sema/SemaExpr.cpp:7749
+// id (or strictly compatible object type) -> T^
+if (getLangOpts().ObjC1 && 
RHSType->isBlockCompatibleObjCPointerType(Context)) {
   Kind = CK_AnyPointerToBlockPointerCast;

Do we want to allow implicit casts for all object types to block types for 
assignment, or only for null pointers?  We definitely want to allow `nil` to be 
assigned to a block type, but I would lean slightly to requiring an implicit 
cast.

Ideally, I think we'd allow this but warn, because casting from an arbitrary 
ObjC type to a block incorrectly can cause exciting security vulnerabilities if 
it's done incorrectly and we should encourage people to check these casts 
(`nil` is always safe though - as long as somewhere else checks the nullability 
attributes).


Repository:
  rC Clang

https://reviews.llvm.org/D44580



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


[PATCH] D44559: [Sema] Wrong width of result of mul operation

2018-03-17 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

In https://reviews.llvm.org/D44559#1040799, @rjmccall wrote:

> I think we're correct not to warn here and that GCC/ICC are being noisy.  The 
> existence of a temporary promotion to a wider type doesn't justify warning on 
> arithmetic between two operands that are the same size as the ultimate 
> result.  It is totally fair for users to think of this operation as being 
> "closed" on the original type.


Could you please clarify, are you saying that PR35409 
 is not a bug, and clang should 
continue to not warn in those cases?

If we would have "conversion sanitizer" 
, detection of such problems would 
be easy, but without it, right now it is rather hard to detect such issues...


Repository:
  rC Clang

https://reviews.llvm.org/D44559



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


[PATCH] D44426: Fix llvm + clang build with Intel compiler

2018-03-17 Thread Nicolai Hähnle via Phabricator via cfe-commits
nhaehnle added a comment.

I don't think we should add workarounds for broken compilers.


https://reviews.llvm.org/D44426



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


r327768 - Adding nocf_check attribute for cf-protection fine tuning

2018-03-17 Thread Oren Ben Simhon via cfe-commits
Author: orenb
Date: Sat Mar 17 06:31:35 2018
New Revision: 327768

URL: http://llvm.org/viewvc/llvm-project?rev=327768&view=rev
Log:
Adding nocf_check attribute for cf-protection fine tuning

The patch adds nocf_check target independent attribute for disabling checks 
that were enabled by cf-protection flag.
The attribute can be appertained to functions and function pointers.
Attribute name follows GCC's similar attribute name.

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

Added:
cfe/trunk/test/Sema/attr-nocf_check.c
cfe/trunk/test/Sema/attr-nocf_check.cpp
cfe/trunk/test/Sema/nocf_check_attr_not_allowed.c
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/LangOptions.def
cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/test/CodeGen/attributes.c
cfe/trunk/test/CodeGen/cetintrin.c
cfe/trunk/test/CodeGen/x86-cf-protection.c
cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=327768&r1=327767&r2=327768&view=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Mar 17 06:31:35 2018
@@ -1511,7 +1511,7 @@ protected:
 
 /// Extra information which affects how the function is called, like
 /// regparm and the calling convention.
-unsigned ExtInfo : 11;
+unsigned ExtInfo : 12;
 
 /// Used only by FunctionProtoType, put here to pack with the
 /// other bitfields.
@@ -3147,24 +3147,24 @@ public:
   class ExtInfo {
 friend class FunctionType;
 
-// Feel free to rearrange or add bits, but if you go over 11,
+// Feel free to rearrange or add bits, but if you go over 12,
 // you'll need to adjust both the Bits field below and
 // Type::FunctionTypeBitfields.
 
-//   |  CC  |noreturn|produces|nocallersavedregs|regparm|
-//   |0 .. 4|   5|6   |   7 |8 .. 10|
+//   |  CC  |noreturn|produces|nocallersavedregs|regparm|nocfcheck|
+//   |0 .. 4|   5|6   |   7 |8 .. 10|11   |
 //
 // regparm is either 0 (no regparm attribute) or the regparm value+1.
 enum { CallConvMask = 0x1F };
 enum { NoReturnMask = 0x20 };
 enum { ProducesResultMask = 0x40 };
 enum { NoCallerSavedRegsMask = 0x80 };
+enum { NoCfCheckMask = 0x800 };
 enum {
   RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask |
-  NoCallerSavedRegsMask),
+  NoCallerSavedRegsMask | NoCfCheckMask),
   RegParmOffset = 8
 }; // Assumed to be the last field
-
 uint16_t Bits = CC_C;
 
 ExtInfo(unsigned Bits) : Bits(static_cast(Bits)) {}
@@ -3173,12 +3173,13 @@ public:
  // Constructor with no defaults. Use this when you know that you
  // have all the elements (when reading an AST file for example).
  ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
- bool producesResult, bool noCallerSavedRegs) {
+ bool producesResult, bool noCallerSavedRegs, bool NoCfCheck) {
assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
   (producesResult ? ProducesResultMask : 0) |
   (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
-  (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
+  (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | 
+  (NoCfCheck ? NoCfCheckMask : 0);
 }
 
 // Constructor with all defaults. Use when for example creating a
@@ -3192,10 +3193,11 @@ public:
 bool getNoReturn() const { return Bits & NoReturnMask; }
 bool getProducesResult() const { return Bits & ProducesResultMask; }
 bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
+bool getNoCfCheck() const { return Bits & NoCfCheckMask; }
 bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
 
 unsigned getRegParm() const {
-  unsigned RegParm = Bits >> RegParmOffset;
+  unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
   if (RegParm > 0)
 --RegParm;
   return RegParm;
@@ -3234,6 +3236,13 @@ public:
 return ExtInfo(Bits & ~NoCall

[PATCH] D41880: Adding nocf_check attribute for cf-protection fine tuning

2018-03-17 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL327768: Adding nocf_check attribute for cf-protection fine 
tuning (authored by orenb, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41880?vs=136235&id=138816#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41880

Files:
  cfe/trunk/include/clang/AST/Type.h
  cfe/trunk/include/clang/Basic/Attr.td
  cfe/trunk/include/clang/Basic/AttrDocs.td
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Basic/LangOptions.def
  cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/Type.cpp
  cfe/trunk/lib/AST/TypePrinter.cpp
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/lib/Frontend/CompilerInvocation.cpp
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp
  cfe/trunk/lib/Sema/SemaType.cpp
  cfe/trunk/lib/Serialization/ASTReader.cpp
  cfe/trunk/lib/Serialization/ASTWriter.cpp
  cfe/trunk/test/CodeGen/attributes.c
  cfe/trunk/test/CodeGen/cetintrin.c
  cfe/trunk/test/CodeGen/x86-cf-protection.c
  cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
  cfe/trunk/test/Sema/attr-nocf_check.c
  cfe/trunk/test/Sema/attr-nocf_check.cpp
  cfe/trunk/test/Sema/nocf_check_attr_not_allowed.c

Index: cfe/trunk/lib/AST/ASTContext.cpp
===
--- cfe/trunk/lib/AST/ASTContext.cpp
+++ cfe/trunk/lib/AST/ASTContext.cpp
@@ -8241,6 +8241,8 @@
 return QualType();
   if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs())
 return QualType();
+  if (lbaseInfo.getNoCfCheck() != rbaseInfo.getNoCfCheck())
+return QualType();
 
   // FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
   bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
Index: cfe/trunk/lib/AST/TypePrinter.cpp
===
--- cfe/trunk/lib/AST/TypePrinter.cpp
+++ cfe/trunk/lib/AST/TypePrinter.cpp
@@ -801,6 +801,8 @@
<< Info.getRegParm() << ")))";
   if (Info.getNoCallerSavedRegs())
 OS << " __attribute__((no_caller_saved_registers))";
+  if (Info.getNoCfCheck())
+OS << " __attribute__((nocf_check))";
 }
 
 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, 
@@ -1396,7 +1398,7 @@
   // FIXME: When Sema learns to form this AttributedType, avoid printing the
   // attribute again in printFunctionProtoAfter.
   case AttributedType::attr_noreturn: OS << "noreturn"; break;
-
+  case AttributedType::attr_nocf_check: OS << "nocf_check"; break;
   case AttributedType::attr_cdecl: OS << "cdecl"; break;
   case AttributedType::attr_fastcall: OS << "fastcall"; break;
   case AttributedType::attr_stdcall: OS << "stdcall"; break;
Index: cfe/trunk/lib/AST/Type.cpp
===
--- cfe/trunk/lib/AST/Type.cpp
+++ cfe/trunk/lib/AST/Type.cpp
@@ -3129,6 +3129,7 @@
   case AttributedType::attr_uptr:
   case AttributedType::attr_objc_kindof:
   case AttributedType::attr_ns_returns_retained:
+  case AttributedType::attr_nocf_check:
 return false;
   }
   llvm_unreachable("bad attributed type kind");
@@ -3166,6 +3167,7 @@
   case attr_nullable:
   case attr_null_unspecified:
   case attr_objc_kindof:
+  case attr_nocf_check:
 return false;
 
   case attr_pcs:
Index: cfe/trunk/lib/Sema/SemaType.cpp
===
--- cfe/trunk/lib/Sema/SemaType.cpp
+++ cfe/trunk/lib/Sema/SemaType.cpp
@@ -125,6 +125,7 @@
   case AttributeList::AT_NoReturn: \
   case AttributeList::AT_Regparm: \
   case AttributeList::AT_AnyX86NoCallerSavedRegisters: \
+  case AttributeList::AT_AnyX86NoCfCheck: \
 CALLING_CONV_ATTRS_CASELIST
 
 // Microsoft-specific type qualifiers.
@@ -5144,6 +5145,8 @@
 return AttributeList::AT_ObjCOwnership;
   case AttributedType::attr_noreturn:
 return AttributeList::AT_NoReturn;
+  case AttributedType::attr_nocf_check:
+return AttributeList::AT_AnyX86NoCfCheck;
   case AttributedType::attr_cdecl:
 return AttributeList::AT_CDecl;
   case AttributedType::attr_fastcall:
@@ -6609,7 +6612,7 @@
   FunctionTypeUnwrapper unwrapped(S, type);
 
   if (attr.getKind() == AttributeList::AT_NoReturn) {
-if (S.CheckNoReturnAttr(attr))
+if (S.CheckAttrNoArgs(attr))
   return true;
 
 // Delay if this is not a function type.
@@ -6649,7 +6652,7 @@
   }
 
   if (attr.getKind() == AttributeList::AT_AnyX86NoCallerSavedRegisters) {
-if (S.CheckNoCallerSavedRegsAttr(attr))
+if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr))
   return true;
 
 // Delay if this is not a function type.
@@ -6662,6 +6665,27 @@
 return true;
   }
 
+  if (attr.getKind() == AttributeList::AT_AnyX86NoCfCheck) {
+if (!S.getLangOpts().CFProtectionBranch) {
+  S.Diag(attr.getLoc(), diag::warn_nocf_check_attribute

[PATCH] D30863: [clang-format] make docs/tools/{dump_format_style.py, dump_ast_matchers.py} flake8 compliant

2018-03-17 Thread Sylvestre Ledru via Phabricator via cfe-commits
sylvestre.ledru abandoned this revision.
sylvestre.ledru added a comment.

Looks like it doesn't interest anyone to use coding style on it.


https://reviews.llvm.org/D30863



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


[PATCH] D41808: Rename clang link from clang-X.Y to clang-X

2018-03-17 Thread Dimitry Andric via Phabricator via cfe-commits
dim added inline comments.



Comment at: CMakeLists.txt:422
+ "${CLANG_VERSION_MAJOR}" CACHE STRING
 "Version number that will be placed into the clang executable, in the form 
XX.YY")
 set(LIBCLANG_LIBRARY_VERSION

Please update the descriptions too, e.g. "in the form XX".  Though upon reading 
it more closely, where "into the executable" is the version number placed?  
Isn't this meant as "into the clang executable name"?

I would propose:
"Major version number that will be appended to the clang executable name"


https://reviews.llvm.org/D41808



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


r327769 - [cxx_status] Update to match Jacksonville 2018 motions.

2018-03-17 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Sat Mar 17 07:28:47 2018
New Revision: 327769

URL: http://llvm.org/viewvc/llvm-project?rev=327769&view=rev
Log:
[cxx_status] Update to match Jacksonville 2018 motions.

Also rearrange how we list DR motions: rather than listing them as part of some
later standard, list them against the feature they are a DR against. Explicitly
add a description of how we handle DRs.

Modified:
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=327769&r1=327768&r2=327769&view=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sat Mar 17 07:28:47 2018
@@ -56,7 +56,7 @@ each language mode.
 C++11 implementation status
 
 Clang 3.3 and later implement all of the http://www.iso.org/iso/catalogue_detail.htm?csnumber=50372";>ISO
+  href="http://www.iso.org/standard/50372.html";>ISO
   C++ 2011 standard.
 
 By default, Clang builds C++ code according to the C++98 standard, with many
@@ -134,10 +134,15 @@ with http://libcxx.llvm.org/";>l
   Clang 2.9
 
 
-  Lambda expressions
+  Lambda expressions
   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf";>N2927
   Clang 3.1
 
+  
+
+http://wg21.link/p0588r1";>P0588R1 (DR)
+No
+  
 
   Declared type of an expression
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf";>N2343
@@ -195,10 +200,15 @@ with http://libcxx.llvm.org/";>l
   Clang 3.3 (1)
 
 
-  Generalized constant expressions
+  Generalized constant expressions
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf";>N2235
   Clang 3.1
 
+  
+
+http://wg21.link/p0859r0";>P0859R0 (DR)
+No
+  
 
   Alignment support
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf";>N2341
@@ -220,10 +230,15 @@ with http://libcxx.llvm.org/";>l
   Clang 3.0
 
 
-  Inheriting constructors
+  Inheriting constructors
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm";>N2540
   Clang 3.3
 
+  
+
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html";>P0136R1
 (DR)
+Clang 3.9
+  
 
   Explicit conversion operators
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf";>N2437
@@ -296,10 +311,15 @@ with http://libcxx.llvm.org/";>l
   Clang 2.9
 
 
-  Range-based for
+  Range-based for
   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html";>N2930
   Clang 3.0
 
+  
+
+http://wg21.link/p0962r1";>P0962R1 (DR)
+No
+  
 
   Explicit virtual overrides
   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm";>N2928
@@ -427,7 +447,7 @@ change.
 C++14 implementation status
 
 Clang 3.4 and later implement all of the http://www.iso.org/iso/catalogue_detail.htm?csnumber=64029";>ISO
+href="http://www.iso.org/standard/64029.html";>ISO
 C++ 2014 standard.
 
 You can use Clang in C++14 mode with the -std=c++14 option
@@ -521,8 +541,8 @@ version 3.7.
 
 C++17 implementation status
 
-Clang 5 and later implement all the features
-of the C++ 2017 Draft International Standard.
+Clang 5 and later implement all the features of the
+https://www.iso.org/standard/68564.html";>ISO C++ 2017 standard.
 
 You can use Clang in C++17 mode with the -std=c++17 option
 (use -std=c++1z in Clang 4 and earlier).
@@ -619,11 +639,6 @@ of the C++ 2017 Draft International Stan
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0061.html";>P0061R1
   Yes
 
-
-  New specification for inheriting constructors (DR1941 et al)
-  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html";>P0136R1
-  Clang 3.9 (9)
-
 
 
   [[fallthrough]] attribute
@@ -682,13 +697,18 @@ of the C++ 2017 Draft International Stan
   Clang 4
 
 
-  Template argument deduction for class templates
+  Template argument deduction for class templates
   http://wg21.link/p0091r3";>P0091R3
   Clang 5
 

 http://wg21.link/p0512r0";>P0512R0
   
+  
+
+http://wg21.link/p0702r1";>P0702R1 (DR)
+Clang 6
+  
 
   Non-type template parameters with auto type
   http://wg21.link/p0127r2";>P0127R2
@@ -702,7 +722,7 @@ of the C++ 2017 Draft International Stan
 
   Stricter expression evaluation order
   http://wg21.link/p0145r3";>P0145R3
-  Clang 4 (10)
+  Clang 4 (9)
 
 
   http://wg21.link/p0400r0";>P0400R0
@@ -723,10 +743,20 @@ of the C++ 2017 Draft International Stan
   Clang 3.9
 
 
-  Structured bindings
+  Structured bindings
   http://wg21.link

r327770 - [cxx_status] Add entry for the Reflection TS.

2018-03-17 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Sat Mar 17 07:34:21 2018
New Revision: 327770

URL: http://llvm.org/viewvc/llvm-project?rev=327770&view=rev
Log:
[cxx_status] Add entry for the Reflection TS.

Modified:
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=327770&r1=327769&r2=327770&view=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sat Mar 17 07:34:21 2018
@@ -1021,14 +1021,12 @@ and library features that are not part o
   -fmodules-ts
   WIP
 
-
 
   [TS] Transactional Memory
   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4514.pdf";>N4514


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


[PATCH] D44581: [Driver] Fix the descriptions for -Tdata and -Ttext options

2018-03-17 Thread Aaron Smith via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327775: [Driver] Fix the descriptions for -Tdata and -Ttext 
options (authored by asmith, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D44581

Files:
  include/clang/Driver/Options.td


Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -418,9 +418,9 @@
 def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group,
   MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
 def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group,
-  MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
+  MetaVarName<"">, HelpText<"Set starting address of DATA to ">;
 def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group,
-  MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
+  MetaVarName<"">, HelpText<"Set starting address of TEXT to ">;
 def T : JoinedOrSeparate<["-"], "T">, Group,
   MetaVarName<"

r327775 - [Driver] Fix the descriptions for -Tdata and -Ttext options

2018-03-17 Thread Aaron Smith via cfe-commits
Author: asmith
Date: Sat Mar 17 08:24:35 2018
New Revision: 327775

URL: http://llvm.org/viewvc/llvm-project?rev=327775&view=rev
Log:
[Driver] Fix the descriptions for -Tdata and -Ttext options

Reviewers: llvm-commits

Subscribers: cfe-commits

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

Modified:
cfe/trunk/include/clang/Driver/Options.td

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=327775&r1=327774&r2=327775&view=diff
==
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Sat Mar 17 08:24:35 2018
@@ -418,9 +418,9 @@ def S : Flag<["-"], "S">, Flags<[DriverO
 def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group,
   MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
 def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group,
-  MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
+  MetaVarName<"">, HelpText<"Set starting address of DATA to ">;
 def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group,
-  MetaVarName<"">, HelpText<"Set starting address of BSS to ">;
+  MetaVarName<"">, HelpText<"Set starting address of TEXT to ">;
 def T : JoinedOrSeparate<["-"], "T">, Group,
   MetaVarName<"

[PATCH] D44559: [Sema] Wrong width of result of mul operation

2018-03-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

In https://reviews.llvm.org/D44559#1040928, @lebedev.ri wrote:

> In https://reviews.llvm.org/D44559#1040799, @rjmccall wrote:
>
> > I think we're correct not to warn here and that GCC/ICC are being noisy.  
> > The existence of a temporary promotion to a wider type doesn't justify 
> > warning on arithmetic between two operands that are the same size as the 
> > ultimate result.  It is totally fair for users to think of this operation 
> > as being "closed" on the original type.
>
>
> Could you please clarify, are you saying that PR35409 
>  is not a bug, and clang should 
> continue to not warn in those cases?


Correct.

> If we would have "conversion sanitizer" 
> , detection of such problems 
> would be easy, but without it, right now it is rather hard to detect such 
> issues...

What issue?  That arithmetic can overflow?


Repository:
  rC Clang

https://reviews.llvm.org/D44559



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


[PATCH] D44559: [Sema] Wrong width of result of mul operation

2018-03-17 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

In https://reviews.llvm.org/D44559#1041001, @rjmccall wrote:

> In https://reviews.llvm.org/D44559#1040928, @lebedev.ri wrote:
>
> > In https://reviews.llvm.org/D44559#1040799, @rjmccall wrote:
> >
> > > I think we're correct not to warn here and that GCC/ICC are being noisy.  
> > > The existence of a temporary promotion to a wider type doesn't justify 
> > > warning on arithmetic between two operands that are the same size as the 
> > > ultimate result.  It is totally fair for users to think of this operation 
> > > as being "closed" on the original type.
> >
> >
> > Could you please clarify, are you saying that PR35409 
> >  is not a bug, and clang 
> > should continue to not warn in those cases?
>
>
> Correct.
>
> > If we would have "conversion sanitizer" 
> > , detection of such problems 
> > would be easy, but without it, right now it is rather hard to detect such 
> > issues...
>
> What issue?  That arithmetic can overflow?


But this isn't about overflow. Arithmetic overflow issues are nicely detectable 
with current UBSan (+`-fsanitize=integer`, for unsigned).
This is about the **lack** of detectable overflow - implicit cast to `int`, 
multiplication of `int`'s (which means no overflow actually happened),
and then implicit integer demotion (which changes the "integer's value", for 
which there is no sanitizer, yet).

There is currently no way to detect this, at least in clang.
And it's not trivial to detect/debug such problems, which is exactly why a 
warning would be nice.


Repository:
  rC Clang

https://reviews.llvm.org/D44559



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


[PATCH] D42966: Fix USR generation in the presence of #line directives or linemarkes

2018-03-17 Thread Mikhail Ramalho via Phabricator via cfe-commits
mikhail.ramalho added a comment.

ping.


Repository:
  rC Clang

https://reviews.llvm.org/D42966



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


[PATCH] D44426: Fix llvm + clang build with Intel compiler

2018-03-17 Thread Zachary Turner via Phabricator via cfe-commits
zturner added a comment.

In https://reviews.llvm.org/D44426#1040938, @nhaehnle wrote:

> I don't think we should add workarounds for broken compilers.


I don't follow.  What should we do then?  If LLVM doesn't compile on a compiler 
which we claim is supported, then how should we proceed?


https://reviews.llvm.org/D44426



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


[PATCH] D44559: [Sema] Wrong width of result of mul operation

2018-03-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

In https://reviews.llvm.org/D44559#1041002, @lebedev.ri wrote:

> In https://reviews.llvm.org/D44559#1041001, @rjmccall wrote:
>
> > In https://reviews.llvm.org/D44559#1040928, @lebedev.ri wrote:
> >
> > > In https://reviews.llvm.org/D44559#1040799, @rjmccall wrote:
> > >
> > > > I think we're correct not to warn here and that GCC/ICC are being 
> > > > noisy.  The existence of a temporary promotion to a wider type doesn't 
> > > > justify warning on arithmetic between two operands that are the same 
> > > > size as the ultimate result.  It is totally fair for users to think of 
> > > > this operation as being "closed" on the original type.
> > >
> > >
> > > Could you please clarify, are you saying that PR35409 
> > >  is not a bug, and clang 
> > > should continue to not warn in those cases?
> >
> >
> > Correct.
> >
> > > If we would have "conversion sanitizer" 
> > > , detection of such problems 
> > > would be easy, but without it, right now it is rather hard to detect such 
> > > issues...
> >
> > What issue?  That arithmetic can overflow?
>
>
> But this isn't about overflow. Arithmetic overflow issues are nicely 
> detectable with current UBSan (+`-fsanitize=integer`, for unsigned).
>  This is about the **lack** of detectable overflow - implicit cast to `int`, 
> multiplication of `int`'s (which means no overflow actually happened),
>  and then implicit integer demotion (which changes the "integer's value", for 
> which there is no sanitizer, yet).


The situation is effectively overflow in the original type of the operands.  
That overflow does not have UB, and its formal moment is slightly different 
because it's tied to the conversion rather than the actual arithmetic, but, in 
the end, the observable effect is overflow.  From a language-design 
perspective, C would not be able to get away with implicitly promoting operands 
to a wider type if the result of the arithmetic after truncation weren't 
consistent with just doing the arithmetic in the narrower type.

> There is currently no way to detect this, at least in clang.
>  And it's not trivial to detect/debug such problems, which is exactly why a 
> warning would be nice.

I think a "sanitizer" that tried to report when a integer value was used after 
undergoing an implicit conversion that changed its arithmetic value — but not 
when the value first passed through an explicit cast — would be a really 
interesting feature.

This patch, however, is contrary to the design of -Wconversion, which does 
attempt to avoid warning in cases where the user might reasonably see an 
operation as "really" being performed in its operand type.  If you want to 
argue that we should change the design of -Wconversion, that is a broader 
conversation that you should take to cfe-dev.


Repository:
  rC Clang

https://reviews.llvm.org/D44559



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


[PATCH] D44534: Fix codegen for structured binding binding in conditions

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327780: Fix codegen for structured binding binding in 
conditions (authored by lichray, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D44534

Files:
  lib/CodeGen/CGStmt.cpp
  test/Parser/decomposed-condition.cpp

Index: lib/CodeGen/CGStmt.cpp
===
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -608,7 +608,7 @@
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // If the condition constant folds and can be elided, try to avoid emitting
   // the condition and the dead arm of the if/else.
@@ -705,7 +705,7 @@
   RunCleanupsScope ConditionScope(*this);
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // Evaluate the conditional in the while header.  C99 6.8.5.1: The
   // evaluation of the controlling expression takes place before each
@@ -865,7 +865,7 @@
 // If the for statement has a condition scope, emit the local variable
 // declaration.
 if (S.getConditionVariable()) {
-  EmitAutoVarDecl(*S.getConditionVariable());
+  EmitDecl(*S.getConditionVariable());
 }
 
 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
@@ -1574,7 +1574,7 @@
   // Emit the condition variable if needed inside the entire cleanup scope
   // used by this special case for constant folded switches.
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // At this point, we are no longer "within" a switch instance, so
   // we can temporarily enforce this to ensure that any embedded case
@@ -1603,7 +1603,7 @@
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
   llvm::Value *CondV = EmitScalarExpr(S.getCond());
 
   // Create basic block to hold stuff that comes after switch
Index: test/Parser/decomposed-condition.cpp
===
--- test/Parser/decomposed-condition.cpp
+++ test/Parser/decomposed-condition.cpp
@@ -1,5 +1,20 @@
 // RUN: %clang_cc1 -std=c++1z %s -verify
 
+namespace std {
+  template struct tuple_size;
+  template struct tuple_element;
+}
+
+struct Get {
+  template int get() { return 0; }
+  operator bool() { return true; }
+};
+
+namespace std {
+  template<> struct tuple_size { static constexpr int value = 1; };
+  template<> struct tuple_element<0, Get> { using type = int; };
+}
+
 struct Na {
   bool flag;
   float data;
@@ -17,29 +32,35 @@
 Na g();
 
 namespace CondInIf {
-void h() {
+int h() {
   if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  if (auto [value] = Get()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInIf
 
 namespace CondInWhile {
-void h() {
+int h() {
   while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  while (auto [value] = Get()) // expected-warning{{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInWhile
 
 namespace CondInFor {
-void h() {
+int h() {
   for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  for (; auto [value] = Get();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInFor
 
@@ -52,10 +73,15 @@
 };
 
 namespace CondInSwitch {
-void h(IntegerLike x) {
+int h(IntegerLike x) {
   switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
 ;
+ 

[PATCH] D44602: [clang-tidy] readability-function-size: add VariableThreshold param.

2018-03-17 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri created this revision.
lebedev.ri added reviewers: alexfh, hokein, xazax.hun, JonasToth, aaron.ballman.
lebedev.ri added a project: clang-tools-extra.
Herald added a subscriber: rnkovacs.

Pretty straight-forward, just count all the variable declarations in the 
function's body, and if more than the configured threshold - do complain.

Note that this continues perverse practice of disabling the new option by 
default.
I'm not certain where is the balance point between not being too noisy, and 
actually enforcing the good practice.
If we really want to not disable this by default, but also to not cause too 
many new warnings, we could default to 50 or so.
But that is a lot of variables too...

  

I was able to find one coding style referencing variable count:

- https://www.kernel.org/doc/html/v4.15/process/coding-style.html#functions

  > Another measure of the function is the number of local variables. They 
shouldn’t exceed 5-10, or you’re doing something wrong.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44602

Files:
  clang-tidy/readability/FunctionSizeCheck.cpp
  clang-tidy/readability/FunctionSizeCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/readability-function-size.rst
  test/clang-tidy/readability-function-size.cpp

Index: test/clang-tidy/readability-function-size.cpp
===
--- test/clang-tidy/readability-function-size.cpp
+++ test/clang-tidy/readability-function-size.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}]}' -- -std=c++11
+// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}, {key: readability-function-size.VariableThreshold, value: 1}]}' -- -std=c++11
 
 // Bad formatting is intentional, don't run clang-format over the whole file!
 
@@ -64,7 +64,7 @@
 
 void baz0() { // 1
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'baz0' exceeds recommended size/complexity
-  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 27 lines including whitespace and comments (threshold 0)
+  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 28 lines including whitespace and comments (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 9 statements (threshold 0)
   int a;
   { // 2
@@ -87,14 +87,15 @@
 }
   }
   macro()
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
-// CHECK-MESSAGES: :[[@LINE-28]]:25: note: expanded from macro 'macro'
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
+  // CHECK-MESSAGES: :[[@LINE-28]]:25: note: expanded from macro 'macro'
+  // CHECK-MESSAGES: :[[@LINE-27]]:6: note: 9 variables (threshold 1)
 }
 
 // check that nested if's are not reported. this was broken initially
 void nesting_if() { // 1
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'nesting_if' exceeds recommended size/complexity
-  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 22 lines including whitespace and comments (threshold 0)
+  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 18 statements (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-4]]:6: note: 6 branches (threshold 0)
   if (true) { // 2
@@ -114,12 +115,13 @@
   } else if (true) { // 2
  int j;
   }
+  // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 6 variables (threshold 1)
 }
 
 // however this should warn
 void bad_if_nesting() { // 1
 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bad_if_nesting' exceeds recommended size/complexity
-// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 22 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 12 statements (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-4]]:6: note: 4 branches (threshold 0)
   if (true) {// 2
@@ -139,4 +141,49 @@
   }
 }
   }
+  // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 4 variables (threshold 1)
 }
+
+void variables_0() {
+  int i;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_0' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MES

r327780 - Fix codegen for structured binding binding in conditions

2018-03-17 Thread Zhihao Yuan via cfe-commits
Author: lichray
Date: Sat Mar 17 14:01:27 2018
New Revision: 327780

URL: http://llvm.org/viewvc/llvm-project?rev=327780&view=rev
Log:
Fix codegen for structured binding binding in conditions

Summary:
The codegen for conditions assumes that a normal variable declaration is used 
in a condition, but this is not the case when a structured binding is used.

This fixes [PR36747](http://llvm.org/pr36747).

Thanks Nicolas Lesser for contributing the patch.

Reviewers: lichray, rsmith

Reviewed By: lichray

Subscribers: cfe-commits

Tags: #clang

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

Modified:
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/test/Parser/decomposed-condition.cpp

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=327780&r1=327779&r2=327780&view=diff
==
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Sat Mar 17 14:01:27 2018
@@ -608,7 +608,7 @@ void CodeGenFunction::EmitIfStmt(const I
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // If the condition constant folds and can be elided, try to avoid emitting
   // the condition and the dead arm of the if/else.
@@ -705,7 +705,7 @@ void CodeGenFunction::EmitWhileStmt(cons
   RunCleanupsScope ConditionScope(*this);
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // Evaluate the conditional in the while header.  C99 6.8.5.1: The
   // evaluation of the controlling expression takes place before each
@@ -865,7 +865,7 @@ void CodeGenFunction::EmitForStmt(const
 // If the for statement has a condition scope, emit the local variable
 // declaration.
 if (S.getConditionVariable()) {
-  EmitAutoVarDecl(*S.getConditionVariable());
+  EmitDecl(*S.getConditionVariable());
 }
 
 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
@@ -1574,7 +1574,7 @@ void CodeGenFunction::EmitSwitchStmt(con
   // Emit the condition variable if needed inside the entire cleanup scope
   // used by this special case for constant folded switches.
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // At this point, we are no longer "within" a switch instance, so
   // we can temporarily enforce this to ensure that any embedded case
@@ -1603,7 +1603,7 @@ void CodeGenFunction::EmitSwitchStmt(con
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
   llvm::Value *CondV = EmitScalarExpr(S.getCond());
 
   // Create basic block to hold stuff that comes after switch

Modified: cfe/trunk/test/Parser/decomposed-condition.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/decomposed-condition.cpp?rev=327780&r1=327779&r2=327780&view=diff
==
--- cfe/trunk/test/Parser/decomposed-condition.cpp (original)
+++ cfe/trunk/test/Parser/decomposed-condition.cpp Sat Mar 17 14:01:27 2018
@@ -1,5 +1,20 @@
 // RUN: %clang_cc1 -std=c++1z %s -verify
 
+namespace std {
+  template struct tuple_size;
+  template struct tuple_element;
+}
+
+struct Get {
+  template int get() { return 0; }
+  operator bool() { return true; }
+};
+
+namespace std {
+  template<> struct tuple_size { static constexpr int value = 1; };
+  template<> struct tuple_element<0, Get> { using type = int; };
+}
+
 struct Na {
   bool flag;
   float data;
@@ -17,29 +32,35 @@ Rst f();
 Na g();
 
 namespace CondInIf {
-void h() {
+int h() {
   if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit 
structured binding declaration in a condition}}
 ;
   if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit 
structured binding declaration in a condition}} expected-error {{value of type 
'Na' is not contextually convertible to 'bool'}}
 ;
+  if (auto [value] = Get()) // expected-warning {{ISO C++17 does not permit 
structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInIf
 
 namespace CondInWhile {
-void h() {
+int h() {
   while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit 
structured binding declaration in a condition}}
 ;
   while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit 
structured binding declaration in a condition}} expected-error {{value of type 
'Na' is not contextually convertible to 'bool'}}
 ;
+  while (auto [value] = Get()) // expected-warning{{ISO C++17 does not permit 
structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInWhile
 
 namespace CondInFo

r327781 - Implement DR2229, which prohibits unnamed bit-fields from having qualifiers in C++.

2018-03-17 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Sat Mar 17 14:08:40 2018
New Revision: 327781

URL: http://llvm.org/viewvc/llvm-project?rev=327781&view=rev
Log:
Implement DR2229, which prohibits unnamed bit-fields from having qualifiers in 
C++.

Added:
cfe/trunk/test/CXX/drs/dr22xx.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CXX/class/class.bit/p2.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=327781&r1=327780&r2=327781&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Mar 17 14:08:40 
2018
@@ -1586,6 +1586,8 @@ def err_not_integral_type_bitfield : Err
   "bit-field %0 has non-integral type %1">;
 def err_not_integral_type_anon_bitfield : Error<
   "anonymous bit-field has non-integral type %0">;
+def err_anon_bitfield_qualifiers : Error<
+  "anonymous bit-field cannot have qualifiers">;
 def err_member_function_initialization : Error<
   "initializer on function does not look like a pure-specifier">;
 def err_non_virtual_pure : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=327781&r1=327780&r2=327781&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Mar 17 14:08:40 2018
@@ -14856,6 +14856,13 @@ FieldDecl *Sema::CheckFieldDecl(Declarat
 InvalidDecl = true;
   }
 
+  // Anonymous bit-fields cannot be cv-qualified (CWG 2229).
+  if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth &&
+  T.hasQualifiers()) {
+InvalidDecl = true;
+Diag(Loc, diag::err_anon_bitfield_qualifiers);
+  }
+
   // C99 6.7.2.1p8: A member of a structure or union may have any type other
   // than a variably modified type.
   if (!InvalidDecl && T->isVariablyModifiedType()) {

Modified: cfe/trunk/test/CXX/class/class.bit/p2.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.bit/p2.cpp?rev=327781&r1=327780&r2=327781&view=diff
==
--- cfe/trunk/test/CXX/class/class.bit/p2.cpp (original)
+++ cfe/trunk/test/CXX/class/class.bit/p2.cpp Sat Mar 17 14:08:40 2018
@@ -9,7 +9,7 @@ A a = { };
 A a2 = { 1 }; // expected-error{{excess elements in struct initializer}}
 
 struct B {
-  const int : 0;
+  const int : 0; // expected-error{{anonymous bit-field cannot have 
qualifiers}}
 };
 
 B b;

Added: cfe/trunk/test/CXX/drs/dr22xx.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr22xx.cpp?rev=327781&view=auto
==
--- cfe/trunk/test/CXX/drs/dr22xx.cpp (added)
+++ cfe/trunk/test/CXX/drs/dr22xx.cpp Sat Mar 17 14:08:40 2018
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify 
-fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify 
-fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify 
-fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify 
-fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr2229 { // dr2229: yes
+struct AnonBitfieldQualifiers {
+  const unsigned : 1; // expected-error {{anonymous bit-field cannot have 
qualifiers}}
+  volatile unsigned : 1; // expected-error {{anonymous bit-field cannot have 
qualifiers}}
+  const volatile unsigned : 1; // expected-error {{anonymous bit-field cannot 
have qualifiers}}
+
+  unsigned : 1;
+  const unsigned i1 : 1;
+  volatile unsigned i2 : 1;
+  const volatile unsigned i3 : 1;
+};
+}


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


[PATCH] D44602: [clang-tidy] readability-function-size: add VariableThreshold param.

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



Comment at: docs/ReleaseNotes.rst:122
 
+- Added `VariableThreshold` to `readability-function-size
+  
`_
 check

Will be good idea to add //option// to clarify improvement.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44602



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


[PATCH] D44602: [clang-tidy] readability-function-size: add VariableThreshold param.

2018-03-17 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 138830.
lebedev.ri marked an inline comment as done.
lebedev.ri added a comment.

Adjusted ReleaseNotes change.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44602

Files:
  clang-tidy/readability/FunctionSizeCheck.cpp
  clang-tidy/readability/FunctionSizeCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/readability-function-size.rst
  test/clang-tidy/readability-function-size.cpp

Index: test/clang-tidy/readability-function-size.cpp
===
--- test/clang-tidy/readability-function-size.cpp
+++ test/clang-tidy/readability-function-size.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}]}' -- -std=c++11
+// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}, {key: readability-function-size.VariableThreshold, value: 1}]}' -- -std=c++11
 
 // Bad formatting is intentional, don't run clang-format over the whole file!
 
@@ -64,7 +64,7 @@
 
 void baz0() { // 1
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'baz0' exceeds recommended size/complexity
-  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 27 lines including whitespace and comments (threshold 0)
+  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 28 lines including whitespace and comments (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 9 statements (threshold 0)
   int a;
   { // 2
@@ -87,14 +87,15 @@
 }
   }
   macro()
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
-// CHECK-MESSAGES: :[[@LINE-28]]:25: note: expanded from macro 'macro'
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
+  // CHECK-MESSAGES: :[[@LINE-28]]:25: note: expanded from macro 'macro'
+  // CHECK-MESSAGES: :[[@LINE-27]]:6: note: 9 variables (threshold 1)
 }
 
 // check that nested if's are not reported. this was broken initially
 void nesting_if() { // 1
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'nesting_if' exceeds recommended size/complexity
-  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 22 lines including whitespace and comments (threshold 0)
+  // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 18 statements (threshold 0)
   // CHECK-MESSAGES: :[[@LINE-4]]:6: note: 6 branches (threshold 0)
   if (true) { // 2
@@ -114,12 +115,13 @@
   } else if (true) { // 2
  int j;
   }
+  // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 6 variables (threshold 1)
 }
 
 // however this should warn
 void bad_if_nesting() { // 1
 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bad_if_nesting' exceeds recommended size/complexity
-// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 22 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-3]]:6: note: 12 statements (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-4]]:6: note: 4 branches (threshold 0)
   if (true) {// 2
@@ -139,4 +141,49 @@
   }
 }
   }
+  // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 4 variables (threshold 1)
 }
+
+void variables_0() {
+  int i;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_0' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_1(int i) {
+  int j;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_1' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_2() {
+  int i[2];
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'variables_2' exceeds recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 statements (threshold 0)
+void variables_3() {
+  int i;
+  int j;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:6: warning

[PATCH] D44093: [BUILTINS] structure pretty printer

2018-03-17 Thread Paul Semel via Phabricator via cfe-commits
paulsemel updated this revision to Diff 138832.
paulsemel added a comment.

Applied Aaron's suggestions
Added Sema tests for the typechecking


Repository:
  rC Clang

https://reviews.llvm.org/D44093

Files:
  include/clang/Basic/Builtins.def
  lib/CodeGen/CGBuiltin.cpp
  lib/Sema/SemaChecking.cpp
  test/CodeGen/dump-struct-builtin.c
  test/Sema/builtin-dump-struct.c

Index: test/Sema/builtin-dump-struct.c
===
--- /dev/null
+++ test/Sema/builtin-dump-struct.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fsyntax-only -fno-spell-checking -verify %s
+
+void invalid_uses() {
+  struct A {
+  };
+  struct A a;
+  void *b;
+  int (*goodfunc)(const char *, ...);
+  int (*badfunc1)(const char *);
+  int (*badfunc2)(int, ...);
+  void (*badfunc3)(const char *, ...);
+
+  __builtin_dump_struct(); // expected-error {{too few arguments to function call, expected 2, have 0}}
+  __builtin_dump_struct(1);// expected-error {{too few arguments to function call, expected 2, have 1}}
+  __builtin_dump_struct(1, 2); // expected-error {{passing 'int' to parameter of incompatible type 'structure pointer type': type mismatch at 1st parameter ('int' vs 'structure pointer type')}}
+  __builtin_dump_struct(&a, 2);// expected-error {{passing 'int' to parameter of incompatible type 'int (*)(const char *, ...)': type mismatch at 2nd parameter ('int' vs 'int (*)(const char *, ...)')}}
+  __builtin_dump_struct(b, &goodfunc); // expected-error {{passing 'void *' to parameter of incompatible type 'structure pointer type': type mismatch at 1st parameter ('void *' vs 'structure pointer type')}}
+  __builtin_dump_struct(&a, badfunc1); // expected-error {{passing 'int (*)(const char *)' to parameter of incompatible type 'int (*)(const char *, ...)': type mismatch at 2nd parameter ('int (*)(const char *)' vs 'int (*)(const char *, ...)')}}
+  __builtin_dump_struct(&a, badfunc2); // expected-error {{passing 'int (*)(int, ...)' to parameter of incompatible type 'int (*)(const char *, ...)': type mismatch at 2nd parameter ('int (*)(int, ...)' vs 'int (*)(const char *, ...)')}}
+  __builtin_dump_struct(&a, badfunc3); // expected-error {{passing 'void (*)(const char *, ...)' to parameter of incompatible type 'int (*)(const char *, ...)': type mismatch at 2nd parameter ('void (*)(const char *, ...)' vs 'int (*)(const char *, ...)')}}
+  __builtin_dump_struct(a, goodfunc);  // expected-error {{passing 'struct A' to parameter of incompatible type 'structure pointer type': type mismatch at 1st parameter ('struct A' vs 'structure pointer type')}}
+}
+
+void valid_uses() {
+  struct A {
+  };
+  union B {
+  };
+
+  int (*goodfunc)(const char *, ...);
+  struct A a;
+  union B b;
+
+  __builtin_dump_struct(&a, goodfunc);
+  __builtin_dump_struct(&b, goodfunc);
+}
Index: test/CodeGen/dump-struct-builtin.c
===
--- /dev/null
+++ test/CodeGen/dump-struct-builtin.c
@@ -0,0 +1,254 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+#include "Inputs/stdio.h"
+
+void unit1() {
+  struct U1A {
+short a;
+  };
+
+  struct U1A a = {
+  .a = 12,
+  };
+
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[RES1:%[0-9]+]] = getelementptr inbounds %struct.U1A, %struct.U1A* %a, i32 0, i32 0
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[LOAD1:%[0-9]+]] = load i16, i16* [[RES1]],
+  // CHECK: call i32 (i8*, ...) @printf({{.*}}, i16 [[LOAD1]])
+  // CHECK: call i32 (i8*, ...) @printf(
+  __builtin_dump_struct(&a, &printf);
+}
+
+void unit2() {
+  struct U2A {
+unsigned short a;
+  };
+
+  struct U2A a = {
+  .a = 12,
+  };
+
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[RES1:%[0-9]+]] = getelementptr inbounds %struct.U2A, %struct.U2A* %a, i32 0, i32 0
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[LOAD1:%[0-9]+]] = load i16, i16* [[RES1]],
+  // CHECK: call i32 (i8*, ...) @printf({{.*}}, i16 [[LOAD1]])
+  // CHECK: call i32 (i8*, ...) @printf(
+  __builtin_dump_struct(&a, &printf);
+}
+
+void unit3() {
+  struct U3A {
+int a;
+  };
+
+  struct U3A a = {
+  .a = 12,
+  };
+
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[RES1:%[0-9]+]] = getelementptr inbounds %struct.U3A, %struct.U3A* %a, i32 0, i32 0
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[LOAD1:%[0-9]+]] = load i32, i32* [[RES1]],
+  // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[LOAD1]])
+  // CHECK: call i32 (i8*, ...) @printf(
+  __builtin_dump_struct(&a, &printf);
+}
+
+void unit4() {
+  struct U4A {
+unsigned int a;
+  };
+
+  struct U4A a = {
+  .a = 12,
+  };
+
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[RES1:%[0-9]+]] = getelementptr inbounds %struct.U4A, %struct.U4A* %a, i32 0, i32 0
+  // CHECK: call i32 (i8*, ...) @printf(
+  // CHECK: [[LOAD1:%[0-9]+]] = load i32, i32* [[RES1]],
+  // CHECK: call i32 (i8*

r327782 - [C++17] Allow an empty expression in an if init statement

2018-03-17 Thread Zhihao Yuan via cfe-commits
Author: lichray
Date: Sat Mar 17 14:42:10 2018
New Revision: 327782

URL: http://llvm.org/viewvc/llvm-project?rev=327782&view=rev
Log:
[C++17] Allow an empty expression in an if init statement

Summary:
This fixes [PR35381](https://llvm.org/pr35381) and an additional bug where 
clang didn't warn about the C++17 extension when having an expression in the 
init statement.

Thanks Nicolas Lesser for contributing the patch.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: erik.pilkington, cfe-commits

Tags: #clang

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

Modified:
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=327782&r1=327781&r2=327782&view=diff
==
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sat Mar 17 14:42:10 2018
@@ -1744,17 +1744,34 @@ Sema::ConditionResult Parser::ParseCXXCo
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX11Attributes(attrs);
 
+  const auto WarnOnInit = [this, &CK] {
+Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+? diag::warn_cxx14_compat_init_statement
+: diag::ext_init_statement)
+<< (CK == Sema::ConditionKind::Switch);
+  };
+
   // Determine what kind of thing we have.
   switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {
   case ConditionOrInitStatement::Expression: {
 ProhibitAttributes(attrs);
 
+// We can have an empty expression here.
+//   if (; true);
+if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
+  SourceLocation SemiLoc = ConsumeToken();
+  *InitStmt = Actions.ActOnNullStmt(SemiLoc);
+  return ParseCXXCondition(nullptr, Loc, CK);
+}
+
 // Parse the expression.
 ExprResult Expr = ParseExpression(); // expression
 if (Expr.isInvalid())
   return Sema::ConditionError();
 
 if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
   *InitStmt = Actions.ActOnExprStmt(Expr.get());
   ConsumeToken();
   return ParseCXXCondition(nullptr, Loc, CK);
@@ -1764,10 +1781,7 @@ Sema::ConditionResult Parser::ParseCXXCo
   }
 
   case ConditionOrInitStatement::InitStmtDecl: {
-Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-? diag::warn_cxx14_compat_init_statement
-: diag::ext_init_statement)
-<< (CK == Sema::ConditionKind::Switch);
+WarnOnInit();
 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
 DeclGroupPtrTy DG =
 ParseSimpleDeclaration(DeclaratorContext::InitStmtContext, DeclEnd,

Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp?rev=327782&r1=327781&r2=327782&view=diff
==
--- cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp (original)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp Sat Mar 17 14:42:10 2018
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
 
 int f();
 
@@ -10,10 +11,67 @@ void g() {
   }
 }
 
-
 void h() {
   if (int x = f()) // expected-note 2{{previous definition}}
 int x; // expected-error{{redefinition of 'x'}}
   else
 int x; // expected-error{{redefinition of 'x'}}
 }
+
+void ifInitStatement() {
+  int Var = 0;
+
+  if (int I = 0; true) {}
+  if (Var + Var; true) {}
+  if (; true) {}
+#ifdef CPP17
+  // expected-warning@-4 {{if initialization statements are incompatible with 
C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with 
C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with 
C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'if' initialization statements are a C++17 
extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 
extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 
extension}}
+#endif
+}
+
+void switchInitStatement() {
+  int Var = 0;
+
+  switch (int I = 0; Var) {}
+  switch (Var + Var; Var) {}
+  switch (; Var) {}
+#ifdef CPP17
+  // expected-warning@-4 {{switch initialization statements are incompatible 
with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible 
with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible 
with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 
extension}}
+  // expected-warning@-8 {{'switch' ini

[PATCH] D40445: [C++17] Allow an empty expression in an if init statement

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327782: [C++17] Allow an empty expression in an if init 
statement (authored by lichray, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D40445

Files:
  lib/Parse/ParseExprCXX.cpp
  test/CXX/stmt.stmt/stmt.select/p3.cpp

Index: test/CXX/stmt.stmt/stmt.select/p3.cpp
===
--- test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
 
 int f();
 
@@ -10,10 +11,67 @@
   }
 }
 
-
 void h() {
   if (int x = f()) // expected-note 2{{previous definition}}
 int x; // expected-error{{redefinition of 'x'}}
   else
 int x; // expected-error{{redefinition of 'x'}}
 }
+
+void ifInitStatement() {
+  int Var = 0;
+
+  if (int I = 0; true) {}
+  if (Var + Var; true) {}
+  if (; true) {}
+#ifdef CPP17
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+#endif
+}
+
+void switchInitStatement() {
+  int Var = 0;
+
+  switch (int I = 0; Var) {}
+  switch (Var + Var; Var) {}
+  switch (; Var) {}
+#ifdef CPP17
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+#endif
+}
+
+// TODO: Better diagnostics for while init statements.
+void whileInitStatement() {
+  while (int I = 10; I--); // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{use of undeclared identifier 'I'}}
+
+  int Var = 10;
+  while (Var + Var; Var--) {} // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+  // expected-warning@-4 {{while loop has empty body}}
+  // expected-note@-5 {{put the semicolon on a separate line to silence this warning}}
+}
+
+// TODO: This is needed because clang can't seem to diagnose invalid syntax after the
+// last loop above. It would be nice to remove this.
+void whileInitStatement2() {
+  while (; false) {} // expected-error {{expected expression}}
+  // expected-warning@-1 {{expression result unused}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+}
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -1744,17 +1744,34 @@
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX11Attributes(attrs);
 
+  const auto WarnOnInit = [this, &CK] {
+Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+? diag::warn_cxx14_compat_init_statement
+: diag::ext_init_statement)
+<< (CK == Sema::ConditionKind::Switch);
+  };
+
   // Determine what kind of thing we have.
   switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {
   case ConditionOrInitStatement::Expression: {
 ProhibitAttributes(attrs);
 
+// We can have an empty expression here.
+//   if (; true);
+if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
+  SourceLocation SemiLoc = ConsumeToken();
+  *InitStmt = Actions.ActOnNullStmt(SemiLoc);
+  return ParseCXXCondition(nullptr, Loc, CK);
+}
+
 // Parse the expression.
 ExprResult Expr = ParseExpression(); // expression
 if (Expr.isInvalid())
   return Sema::ConditionError();
 
 if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
   *InitStmt = Actions.ActOnExprStmt(Expr.get());
   ConsumeToken();
   return ParseCXXCondition(nullptr, Loc, CK);
@@ -1764,10 +1781,7 @@
   }
 
   case ConditionOrInitStatement::InitStmtDecl: {
-Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-? diag::war

[PATCH] D38216: [C++17] Fix class template argument deduction for default constructors without an initializer

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

LGTM




Comment at: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp:17
 };
 extern A x; // expected-error {{requires an initializer}}

Please add one more test to the end of the file saying
```
static A y;
```
as a remainder to the readers.


https://reviews.llvm.org/D38216



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


[PATCH] D44604: Make stdarg.h compatible with FreeBSD

2018-03-17 Thread Alexander Richardson via Phabricator via cfe-commits
arichardson created this revision.
arichardson added reviewers: efriedma, dim.
Herald added subscribers: cfe-commits, krytarowski, sdardis, emaste.

On FreeBSD it is currently not possible to use the clang builtin
headers to build the base system. The build will fail with the
following error if I don't delete the std* headers from the clang
install directory:

  /sources/freebsd-mips/include/stdio.h:72:19: error:
  redefinition of typedef 'va_list' is a C11 feature
  [-Werror,-Wtypedef-redefinition]
  typedef __va_list   va_list;
  ^
  /home/alr48/cheri/output/sdk/lib/clang/7.0.0/include/stdarg.h:30:27:
  note: previous definition is here
  typedef __builtin_va_list va_list;
  
  /sources/freebsd-mips/sys/sys/_stdarg.h:46:11: error: 'va_start' macro 
redefined
  [-Werror,-Wmacro-redefined]
#define   va_start(ap, last)  __builtin_va_start((ap), (last))
  ^
  /home/alr48/cheri/output/sdk/lib/clang/7.0.0/include/stdarg.h:35:9:
  note: previous definition is here
#define va_start(ap, param) __builtin_va_start(ap, param)

FreeBSD includes definitions of va_list, va_copy, etc in the
 header and some files end up including both that
header and .

Only defining the va_* macros if they are not yet defined fixes the
macro redefiniton issue and probably also makes sense for other
operating systems. However, for the va_list typedef I can't think
of a better solution than to also check for _VA_LIST_DECLARED and
define it.


Repository:
  rC Clang

https://reviews.llvm.org/D44604

Files:
  lib/Headers/stdarg.h


Index: lib/Headers/stdarg.h
===
--- lib/Headers/stdarg.h
+++ lib/Headers/stdarg.h
@@ -26,22 +26,33 @@
 #ifndef __STDARG_H
 #define __STDARG_H
 
-#ifndef _VA_LIST
+#if !defined(_VA_LIST) && !defined(_VA_LIST_DECLARED)
 typedef __builtin_va_list va_list;
 #define _VA_LIST
+#define _VA_LIST_DECLARED /* FreeBSD */
 #endif
+#ifndef va_start
 #define va_start(ap, param) __builtin_va_start(ap, param)
+#endif
+#ifndef va_end
 #define va_end(ap)  __builtin_va_end(ap)
+#endif
+#ifndef va_arg
 #define va_arg(ap, type)__builtin_va_arg(ap, type)
+#endif
 
 /* GCC always defines __va_copy, but does not define va_copy unless in c99 mode
  * or -ansi is not specified, since it was not part of C90.
  */
+#ifndef __va_copy
 #define __va_copy(d,s) __builtin_va_copy(d,s)
+#endif
 
 #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || 
!defined(__STRICT_ANSI__)
+#ifndef va_copy
 #define va_copy(dest, src)  __builtin_va_copy(dest, src)
 #endif
+#endif
 
 #ifndef __GNUC_VA_LIST
 #define __GNUC_VA_LIST 1


Index: lib/Headers/stdarg.h
===
--- lib/Headers/stdarg.h
+++ lib/Headers/stdarg.h
@@ -26,22 +26,33 @@
 #ifndef __STDARG_H
 #define __STDARG_H
 
-#ifndef _VA_LIST
+#if !defined(_VA_LIST) && !defined(_VA_LIST_DECLARED)
 typedef __builtin_va_list va_list;
 #define _VA_LIST
+#define _VA_LIST_DECLARED /* FreeBSD */
 #endif
+#ifndef va_start
 #define va_start(ap, param) __builtin_va_start(ap, param)
+#endif
+#ifndef va_end
 #define va_end(ap)  __builtin_va_end(ap)
+#endif
+#ifndef va_arg
 #define va_arg(ap, type)__builtin_va_arg(ap, type)
+#endif
 
 /* GCC always defines __va_copy, but does not define va_copy unless in c99 mode
  * or -ansi is not specified, since it was not part of C90.
  */
+#ifndef __va_copy
 #define __va_copy(d,s) __builtin_va_copy(d,s)
+#endif
 
 #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
+#ifndef va_copy
 #define va_copy(dest, src)  __builtin_va_copy(dest, src)
 #endif
+#endif
 
 #ifndef __GNUC_VA_LIST
 #define __GNUC_VA_LIST 1
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44604: Make stdarg.h compatible with FreeBSD

2018-03-17 Thread Dimitry Andric via Phabricator via cfe-commits
dim added a comment.

I'm fine with either this approach, or with the approach in stdint.h, e.g. 
using `__has_include_next()`, and in that case first including the 
system-provided header before this one.


Repository:
  rC Clang

https://reviews.llvm.org/D44604



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


[PATCH] D44605: [Driver] Default to DWARF 5 for Fuchsia

2018-03-17 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added a reviewer: mcgrathr.
Herald added subscribers: cfe-commits, JDevlieghere, aprantl.

We use DWARF 5 on Fuchsia, make it the toolchain default.


Repository:
  rC Clang

https://reviews.llvm.org/D44605

Files:
  clang/lib/Driver/ToolChains/Fuchsia.h
  clang/test/Driver/fuchsia.c


Index: clang/test/Driver/fuchsia.c
===
--- clang/test/Driver/fuchsia.c
+++ clang/test/Driver/fuchsia.c
@@ -50,6 +50,10 @@
 // CHECK-RELOCATABLE-NOT: "--build-id"
 // CHECK-RELOCATABLE: "-r"
 
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -g 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-DEBUG
+// CHECK-DEBUG: "-dwarf-version=5"
+
 // RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
 // RUN: -fsanitize=safe-stack 2>&1 \
 // RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK
Index: clang/lib/Driver/ToolChains/Fuchsia.h
===
--- clang/lib/Driver/ToolChains/Fuchsia.h
+++ clang/lib/Driver/ToolChains/Fuchsia.h
@@ -56,6 +56,7 @@
   bool isPICDefault() const override { return false; }
   bool isPIEDefault() const override { return true; }
   bool isPICDefaultForced() const override { return false; }
+  unsigned GetDefaultDwarfVersion() const override { return 5; }
   llvm::DebuggerKind getDefaultDebuggerTuning() const override {
 return llvm::DebuggerKind::GDB;
   }


Index: clang/test/Driver/fuchsia.c
===
--- clang/test/Driver/fuchsia.c
+++ clang/test/Driver/fuchsia.c
@@ -50,6 +50,10 @@
 // CHECK-RELOCATABLE-NOT: "--build-id"
 // CHECK-RELOCATABLE: "-r"
 
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -g 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-DEBUG
+// CHECK-DEBUG: "-dwarf-version=5"
+
 // RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
 // RUN: -fsanitize=safe-stack 2>&1 \
 // RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK
Index: clang/lib/Driver/ToolChains/Fuchsia.h
===
--- clang/lib/Driver/ToolChains/Fuchsia.h
+++ clang/lib/Driver/ToolChains/Fuchsia.h
@@ -56,6 +56,7 @@
   bool isPICDefault() const override { return false; }
   bool isPIEDefault() const override { return true; }
   bool isPICDefaultForced() const override { return false; }
+  unsigned GetDefaultDwarfVersion() const override { return 5; }
   llvm::DebuggerKind getDefaultDebuggerTuning() const override {
 return llvm::DebuggerKind::GDB;
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44555: clang-interpreter example cmake fix

2018-03-17 Thread Frederich Munch via Phabricator via cfe-commits
marsupial accepted this revision.
marsupial added a comment.
This revision is now accepted and ready to land.

Sorry 'bout that...
(CMake and quoting make dull boys)


Repository:
  rC Clang

https://reviews.llvm.org/D44555



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


[PATCH] D44604: Make stdarg.h compatible with FreeBSD

2018-03-17 Thread Kamil Rytarowski via Phabricator via cfe-commits
krytarowski added a comment.

This does not fix the potential problem on NetBSD. We define 
`__VA_LIST_DECLARED` (with extra `_` on the beginning).

The proper solution looks to go for:

  #if __STDC_HOSTED__ && __has_include_next()


Repository:
  rC Clang

https://reviews.llvm.org/D44604



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


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

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as not done.
lichray added inline comments.



Comment at: include/support/itoa/itoa.h:29
+UINT64_C(1000),
+UINT64_C(1),
+UINT64_C(10),

EricWF wrote:
> The `UINT64_C` and `UINT32_C` macros are non-standard, so I would rather not 
> use them in a header.
> 
> Additionally, the compiler should correctly convert the integer type to the 
> array's element type, no?
They are from C standard, and I included the corresponding C header.  Dropping 
them gave me `-Wimplicitly-unsigned-literal` warning.


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] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 138841.
lichray marked an inline comment as not done.
lichray added a comment.

Addressing 'Done' comments


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/__errc
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  include/system_error
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_c

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

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 138842.
lichray added a comment.

Keep patches split


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X