r332847 - [CodeGen] Recognize more cases of zero initialization

2018-05-21 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Mon May 21 09:09:54 2018
New Revision: 332847

URL: http://llvm.org/viewvc/llvm-project?rev=332847&view=rev
Log:
[CodeGen] Recognize more cases of zero initialization

If a variable has an initializer, codegen tries to build its value. If
the variable is large in size, building its value requires substantial
resources. It causes strange behavior from user viewpoint: compilation
of huge zero initialized arrays like:

char data_1[2147483648u] = { 0 };

consumes enormous amount of time and memory.

With this change codegen tries to determine if variable initializer is
equivalent to zero initializer. In this case variable value is not
constructed.

This change fixes PR18978.

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

Removed:
cfe/trunk/test/SemaCXX/large-array-init.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/test/CodeGen/const-init.c
cfe/trunk/test/CodeGen/designated-initializers.c
cfe/trunk/test/CodeGen/union-init2.c
cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=332847&r1=332846&r2=332847&view=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 09:09:54 2018
@@ -537,6 +537,13 @@ public:
   bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
  const Expr **Culprit = nullptr) const;
 
+  enum SideEffectsKind {
+SE_NoSideEffects,  ///< Strictly evaluate the expression.
+SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
+   ///< arbitrary unmodeled side effects.
+SE_AllowSideEffects///< Allow any unmodeled side effect.
+  };
+
   /// EvalStatus is a struct with detailed info about an evaluation in 
progress.
   struct EvalStatus {
 /// Whether the evaluated expression has side effects.
@@ -565,6 +572,11 @@ public:
 bool hasSideEffects() const {
   return HasSideEffects;
 }
+
+bool hasUnacceptableSideEffect(SideEffectsKind SEK) {
+  return (SEK < SE_AllowSideEffects && HasSideEffects) ||
+ (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior);
+}
   };
 
   /// EvalResult is a struct with detailed info about an evaluated expression.
@@ -591,13 +603,6 @@ public:
   /// side-effects.
   bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
 
-  enum SideEffectsKind {
-SE_NoSideEffects,  ///< Strictly evaluate the expression.
-SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
-   ///< arbitrary unmodeled side effects.
-SE_AllowSideEffects///< Allow any unmodeled side effect.
-  };
-
   /// EvaluateAsInt - Return true if this is a constant which we can fold and
   /// convert to an integer, using any crazy technique that we want to.
   bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=332847&r1=332846&r2=332847&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 09:09:54 2018
@@ -10312,12 +10312,6 @@ bool Expr::EvaluateAsBooleanCondition(bo
  HandleConversionToBool(Scratch.Val, Result);
 }
 
-static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
-  Expr::SideEffectsKind SEK) {
-  return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) ||
- (SEK < Expr::SE_AllowUndefinedBehavior && 
Result.HasUndefinedBehavior);
-}
-
 bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
  SideEffectsKind AllowSideEffects) const {
   if (!getType()->isIntegralOrEnumerationType())
@@ -10325,7 +10319,7 @@ bool Expr::EvaluateAsInt(APSInt &Result,
 
   EvalResult ExprResult;
   if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() ||
-  hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
+  ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
 return false;
 
   Result = ExprResult.Val.getInt();
@@ -10339,7 +10333,7 @@ bool Expr::EvaluateAsFloat(APFloat &Resu
 
   EvalResult ExprResult;
   if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() ||
-  hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
+  ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
 return false;
 
   Result = ExprResult.Val.getFloat();
@@ -10417,7 +10411,7 @@ bool Expr::EvaluateAs

r338199 - [UBSan] Strengthen pointer checks in 'new' expressions

2018-07-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sat Jul 28 08:33:03 2018
New Revision: 338199

URL: http://llvm.org/viewvc/llvm-project?rev=338199&view=rev
Log:
[UBSan] Strengthen pointer checks in 'new' expressions

With this change compiler generates alignment checks for wider range
of types. Previously such checks were generated only for the record types
with non-trivial default constructor. So the types like:

struct alignas(32) S2 { int x; };
typedef __attribute__((ext_vector_type(2), aligned(32))) float float32x2_t;

did not get checks when allocated by 'new' expression.

This change also optimizes the checks generated for the arrays created
in 'new' expressions. Previously the check was generated for each
invocation of type constructor. Now the check is generated only once
for entire array.

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

Added:
cfe/trunk/test/CodeGenCXX/ubsan-new-checks.cpp
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/lib/CodeGen/CGValue.h
cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=338199&r1=338198&r2=338199&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Sat Jul 28 08:33:03 2018
@@ -685,7 +685,10 @@ void CodeGenFunction::EmitInitializerFor
 AggValueSlot::IsDestructed,
 AggValueSlot::DoesNotNeedGCBarriers,
 AggValueSlot::IsNotAliased,
-overlapForFieldInit(Field));
+overlapForFieldInit(Field),
+AggValueSlot::IsNotZeroed,
+// Checks are made by the code that calls constructor.
+AggValueSlot::IsSanitizerChecked);
 EmitAggExpr(Init, Slot);
 break;
   }
@@ -1869,12 +1872,14 @@ void CodeGenFunction::EnterDtorCleanups(
 ///   zero-initialized before it is constructed
 void CodeGenFunction::EmitCXXAggrConstructorCall(
 const CXXConstructorDecl *ctor, const ArrayType *arrayType,
-Address arrayBegin, const CXXConstructExpr *E, bool zeroInitialize) {
+Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked,
+bool zeroInitialize) {
   QualType elementType;
   llvm::Value *numElements =
 emitArrayLength(arrayType, elementType, arrayBegin);
 
-  EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, zeroInitialize);
+  EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E,
+ NewPointerIsChecked, zeroInitialize);
 }
 
 /// EmitCXXAggrConstructorCall - Emit a loop to call a particular
@@ -1890,6 +1895,7 @@ void CodeGenFunction::EmitCXXAggrConstru
  llvm::Value *numElements,
  Address arrayBase,
  const CXXConstructExpr *E,
+ bool NewPointerIsChecked,
  bool zeroInitialize) {
   // It's legal for numElements to be zero.  This can happen both
   // dynamically, because x can be zero in 'new A[x]', and statically,
@@ -1966,7 +1972,7 @@ void CodeGenFunction::EmitCXXAggrConstru
 
 EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false,
/*Delegating=*/false, curAddr, E,
-   AggValueSlot::DoesNotOverlap);
+   AggValueSlot::DoesNotOverlap, NewPointerIsChecked);
   }
 
   // Go to the next element.
@@ -2002,7 +2008,8 @@ void CodeGenFunction::EmitCXXConstructor
  bool ForVirtualBase,
  bool Delegating, Address This,
  const CXXConstructExpr *E,
- AggValueSlot::Overlap_t Overlap) {
+ AggValueSlot::Overlap_t Overlap,
+ bool NewPointerIsChecked) {
   CallArgList Args;
 
   // Push the this ptr.
@@ -2031,7 +2038,7 @@ void CodeGenFunction::EmitCXXConstructor
/*ParamsToSkip*/ 0, Order);
 
   EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
- Overlap, E->getExprLoc());
+ Overlap, E->getExprLoc(), NewPointerIsChecked);
 }
 
 static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
@@ -2065,14 +2072,13 @@ void CodeGenFunction::EmitCXXConstructor
  Address This,
  CallArgList &Args,
  AggValueSlot::Overlap_t Overlap,
- SourceLocation Loc) {
+ SourceLo

r325661 - Clean up use of C allocation functions

2018-02-20 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Tue Feb 20 18:02:39 2018
New Revision: 325661

URL: http://llvm.org/viewvc/llvm-project?rev=325661&view=rev
Log:
Clean up use of C allocation functions

If the value returned by `malloc`, `calloc` or `realloc` is not checked
for null pointer, this change replaces them for `safe_malloc`,
`safe_calloc` or `safe_realloc`, which are defined in the namespace `llvm`.
These function report fatal error on out of memory.

In the plain C files, assertion statements are added to ensure that memory
is successfully allocated.

The aim of this change is to get better diagnostics of OOM on Windows.

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

Modified:
cfe/trunk/include/clang/Sema/ParsedTemplate.h
cfe/trunk/lib/AST/NestedNameSpecifier.cpp
cfe/trunk/lib/Frontend/CacheTokens.cpp
cfe/trunk/lib/Frontend/Rewrite/HTMLPrint.cpp
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/BuildSystem.cpp
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/tools/libclang/CXString.cpp

Modified: cfe/trunk/include/clang/Sema/ParsedTemplate.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedTemplate.h?rev=325661&r1=325660&r2=325661&view=diff
==
--- cfe/trunk/include/clang/Sema/ParsedTemplate.h (original)
+++ cfe/trunk/include/clang/Sema/ParsedTemplate.h Tue Feb 20 18:02:39 2018
@@ -199,8 +199,7 @@ namespace clang {
SourceLocation LAngleLoc, SourceLocation RAngleLoc,
ArrayRef TemplateArgs,
SmallVectorImpl &CleanupList) {
-
-  TemplateIdAnnotation *TemplateId = new (std::malloc(
+  TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
   totalSizeToAlloc(TemplateArgs.size(
   TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
OperatorKind, OpaqueTemplateName, TemplateKind,

Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NestedNameSpecifier.cpp?rev=325661&r1=325660&r2=325661&view=diff
==
--- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Tue Feb 20 18:02:39 2018
@@ -466,7 +466,7 @@ static void Append(char *Start, char *En
 unsigned NewCapacity = std::max(
 (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
 (unsigned)(BufferSize + (End - Start)));
-char *NewBuffer = static_cast(malloc(NewCapacity));
+char *NewBuffer = static_cast(llvm::safe_malloc(NewCapacity));
 if (BufferCapacity) {
   memcpy(NewBuffer, Buffer, BufferSize);
   free(Buffer);

Modified: cfe/trunk/lib/Frontend/CacheTokens.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CacheTokens.cpp?rev=325661&r1=325660&r2=325661&view=diff
==
--- cfe/trunk/lib/Frontend/CacheTokens.cpp (original)
+++ cfe/trunk/lib/Frontend/CacheTokens.cpp Tue Feb 20 18:02:39 2018
@@ -662,7 +662,8 @@ std::pair PTHWriter::Emit
   //  (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs
 
   // Note that we use 'calloc', so all the bytes are 0.
-  PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey));
+  PTHIdKey *IIDMap = static_cast(
+  llvm::safe_calloc(idcount, sizeof(PTHIdKey)));
 
   // Create the hashtable.
   llvm::OnDiskChainedHashTableGenerator IIOffMap;

Modified: cfe/trunk/lib/Frontend/Rewrite/HTMLPrint.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/HTMLPrint.cpp?rev=325661&r1=325660&r2=325661&view=diff
==
--- cfe/trunk/lib/Frontend/Rewrite/HTMLPrint.cpp (original)
+++ cfe/trunk/lib/Frontend/Rewrite/HTMLPrint.cpp Tue Feb 20 18:02:39 2018
@@ -86,8 +86,7 @@ void HTMLPrinter::HandleTranslationUnit(
 
   // Emit the HTML.
   const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
-  char *Buffer = (char*)malloc(RewriteBuf.size());
-  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
-  Out->write(Buffer, RewriteBuf.size());
-  free(Buffer);
+  std::unique_ptr Buffer(new char[RewriteBuf.size()]);
+  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer.get());
+  Out->write(Buffer.get(), RewriteBuf.size());
 }

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=325661&r1=325660&r2=325661&view=diff
==
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Tue Feb 20 18:02:39 2018
@@ -49,7 +49,8 @@ MacroArgs *MacroArgs::create(const Macro
   if (!ResultEnt) {
 // Allocate memory for a MacroArgs object with the lexer tokens at the end,

[clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-05-24 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed May 24 05:50:56 2017
New Revision: 303735

URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev
Log:
Modify test so that it looks for patterns in stderr as well

With the change https://reviews.llvm.org/D33013 driver will not build
compilation object if command line is invalid, in particular, if
unrecognized option is provided. In such cases it will prints diagnostics
on stderr. The test 'clang-tidy/diagnostic.cpp' checks reaction on
unrecognized option and will fail when D33013 is applied because it checks
only stdout for test patterns and expects the name of diagnostic category
prepared by clang-tidy. With this change the test makes more general check
and must work in either case.

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

Modified:
clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp

Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp?rev=303735&r1=303734&r2=303735&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Wed May 24 05:50:56 
2017
@@ -1,11 +1,11 @@
 // RUN: clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | 
FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
-// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' 
%s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 
-implicit-check-not='{{warning:|error:}}' %s
-// RUN: clang-tidy 
-checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s 
-- -fan-unknown-option | FileCheck -check-prefix=CHECK3 
-implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' 
%s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 
-implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy 
-checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s 
-- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 
-implicit-check-not='{{warning:|error:}}' %s
 // RUN: clang-tidy 
-checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- 
-DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 
-implicit-check-not='{{warning:|error:}}' %s
 
 // CHECK1: error: error reading '{{.*}}.nonexistent.cpp' 
[clang-diagnostic-error]
-// CHECK2: error: unknown argument: '-fan-unknown-option' 
[clang-diagnostic-error]
-// CHECK3: error: unknown argument: '-fan-unknown-option' 
[clang-diagnostic-error]
+// CHECK2: error: unknown argument: '-fan-unknown-option'
+// CHECK3: error: unknown argument: '-fan-unknown-option'
 
 // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' 
changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
 // CHECK3: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' 
changes value


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


r303741 - Method loadFromCommandLine should be able to report errors

2017-05-24 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed May 24 06:57:37 2017
New Revision: 303741

URL: http://llvm.org/viewvc/llvm-project?rev=303741&view=rev
Log:
Method loadFromCommandLine should be able to report errors

Now FixedCompilationDatabase::loadFromCommandLine has no means to report
which error occurred if it fails to create compilation object. This is
a block for implementing D33013, because after that change driver will
refuse to create compilation if command line contains erroneous options.

This change adds additional argument to loadFromCommandLine, which is
assigned error message text if compilation object was not created. This is
the same way as other methods of CompilationDatabase report failure.

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

Modified:
cfe/trunk/include/clang/Tooling/CompilationDatabase.h
cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp
cfe/trunk/lib/Tooling/CommonOptionsParser.cpp
cfe/trunk/lib/Tooling/CompilationDatabase.cpp
cfe/trunk/lib/Tooling/Tooling.cpp
cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp

Modified: cfe/trunk/include/clang/Tooling/CompilationDatabase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/CompilationDatabase.h?rev=303741&r1=303740&r2=303741&view=diff
==
--- cfe/trunk/include/clang/Tooling/CompilationDatabase.h (original)
+++ cfe/trunk/include/clang/Tooling/CompilationDatabase.h Wed May 24 06:57:37 
2017
@@ -176,10 +176,11 @@ public:
   /// the number of arguments before "--", if "--" was found in the argument
   /// list.
   /// \param Argv Points to the command line arguments.
+  /// \param ErrorMsg Contains error text if the function returns null pointer.
   /// \param Directory The base directory used in the FixedCompilationDatabase.
-  static FixedCompilationDatabase *loadFromCommandLine(int &Argc,
-   const char *const *Argv,
-   Twine Directory = ".");
+  static std::unique_ptr loadFromCommandLine(
+  int &Argc, const char *const *Argv, std::string &ErrorMsg,
+  Twine Directory = ".");
 
   /// \brief Constructs a compilation data base from a specified directory
   /// and command line.

Modified: cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp?rev=303741&r1=303740&r2=303741&view=diff
==
--- cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp (original)
+++ cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp Wed May 24 
06:57:37 2017
@@ -52,6 +52,8 @@ std::unique_ptr clan
   TheDriver.setCheckInputsExist(false);
 
   std::unique_ptr C(TheDriver.BuildCompilation(Args));
+  if (!C)
+return nullptr;
 
   // Just print the cc1 options if -### was present.
   if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {

Modified: cfe/trunk/lib/Tooling/CommonOptionsParser.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CommonOptionsParser.cpp?rev=303741&r1=303740&r2=303741&view=diff
==
--- cfe/trunk/lib/Tooling/CommonOptionsParser.cpp (original)
+++ cfe/trunk/lib/Tooling/CommonOptionsParser.cpp Wed May 24 06:57:37 2017
@@ -116,7 +116,11 @@ CommonOptionsParser::CommonOptionsParser
 
   cl::HideUnrelatedOptions(Category);
 
-  Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc, 
argv));
+  std::string ErrorMessage;
+  Compilations =
+  FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
+  if (!Compilations && !ErrorMessage.empty())
+llvm::errs() << ErrorMessage;
   cl::ParseCommandLineOptions(argc, argv, Overview);
   cl::PrintOptionValues();
 
@@ -125,7 +129,6 @@ CommonOptionsParser::CommonOptionsParser
   SourcePathList.empty())
 return;
   if (!Compilations) {
-std::string ErrorMessage;
 if (!BuildPath.empty()) {
   Compilations =
   CompilationDatabase::autoDetectFromDirectory(BuildPath, 
ErrorMessage);

Modified: cfe/trunk/lib/Tooling/CompilationDatabase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CompilationDatabase.cpp?rev=303741&r1=303740&r2=303741&view=diff
==
--- cfe/trunk/lib/Tooling/CompilationDatabase.cpp (original)
+++ cfe/trunk/lib/Tooling/CompilationDatabase.cpp Wed May 24 06:57:37 2017
@@ -27,6 +27,7 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 #include 
 #include 
 using namespace clang;
@@ -150,23 +151,21 @@ private:
 // options.
 class UnusedInputDiagConsumer : public DiagnosticConsumer {
 public:
-  UnusedInputDiagConsumer

r303756 - Driver must return non-zero code on errors in command line

2017-05-24 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed May 24 09:57:17 2017
New Revision: 303756

URL: http://llvm.org/viewvc/llvm-project?rev=303756&view=rev
Log:
Driver must return non-zero code on errors in command line

This is recommit of r302775, reverted in r302777 due to a fail in
clang-tidy. Original mesage is below.

Now if clang driver is given wrong arguments, in some cases it
continues execution and returns zero code. This change fixes this
behavior.

The fix revealed some errors in clang test set.

File test/Driver/gfortran.f90 added in r118203 checks forwarding
gfortran flags to GCC. Now driver reports error on this file, because
the option -working-directory implemented in clang differs from the
option with the same name implemented in gfortran, in clang the option
requires argument, in gfortran does not.

In the file test/Driver/arm-darwin-builtin.c clang is called with
options -fbuiltin-strcat and -fbuiltin-strcpy. These option were removed
in r191435 and now clang reports error on this test.

File arm-default-build-attributes.s uses option -verify, which is not
supported by driver, it is cc1 option.

Similarly, the file split-debug.h uses options -fmodules-embed-all-files
and -fmodule-format=obj, which are not supported by driver.

Other revealed errors are mainly mistypes.

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

Removed:
cfe/trunk/test/Driver/arm-darwin-builtin.c
Modified:
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/test/Driver/aarch64-cpus.c
cfe/trunk/test/Driver/amdgpu-features.c
cfe/trunk/test/Driver/arm-default-build-attributes.s
cfe/trunk/test/Driver/cl-outputs.c
cfe/trunk/test/Driver/clang_f_opts.c
cfe/trunk/test/Driver/cuda-external-tools.cu
cfe/trunk/test/Driver/debug-options.c
cfe/trunk/test/Driver/gfortran.f90
cfe/trunk/test/Driver/split-debug.h
cfe/trunk/test/Driver/unknown-arg.c
cfe/trunk/test/Index/index-attrs.c
cfe/trunk/test/Index/index-attrs.cpp
cfe/trunk/tools/driver/driver.cpp
cfe/trunk/unittests/Driver/ToolChainTest.cpp

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=303756&r1=303755&r2=303756&view=diff
==
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Wed May 24 09:57:17 2017
@@ -598,6 +598,8 @@ Compilation *Driver::BuildCompilation(Ar
   bool CCCPrintPhases;
 
   InputArgList Args = ParseArgStrings(ArgList.slice(1));
+  if (Diags.hasErrorOccurred())
+return nullptr;
 
   // Silence driver warnings if requested
   Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w));

Modified: cfe/trunk/test/Driver/aarch64-cpus.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/aarch64-cpus.c?rev=303756&r1=303755&r2=303756&view=diff
==
--- cfe/trunk/test/Driver/aarch64-cpus.c (original)
+++ cfe/trunk/test/Driver/aarch64-cpus.c Wed May 24 09:57:17 2017
@@ -11,7 +11,7 @@
 // RUN: %clang -target arm64 -### -c %s 2>&1 | FileCheck 
-check-prefix=ARM64-GENERIC %s
 // RUN: %clang -target arm64 -mcpu=generic -### -c %s 2>&1 | FileCheck 
-check-prefix=ARM64-GENERIC %s
 // RUN: %clang -target arm64 -mlittle-endian -### -c %s 2>&1 | FileCheck 
-check-prefix=ARM64-GENERIC %s
-// RUN: %clang -target arm64 -mlittle-endian -mcpu-generic -### -c %s 2>&1 | 
FileCheck -check-prefix=ARM64-GENERIC %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=generic -### -c %s 2>&1 | 
FileCheck -check-prefix=ARM64-GENERIC %s
 
 // ARM64-GENERIC: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
 

Modified: cfe/trunk/test/Driver/amdgpu-features.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/amdgpu-features.c?rev=303756&r1=303755&r2=303756&view=diff
==
--- cfe/trunk/test/Driver/amdgpu-features.c (original)
+++ cfe/trunk/test/Driver/amdgpu-features.c Wed May 24 09:57:17 2017
@@ -1,7 +1,7 @@
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri 
-mamdgpu-debugger-abi=0.0 %s -o 2>&1 \
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri 
-mamdgpu-debugger-abi=0.0 %s -o - 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-MAMDGPU-DEBUGGER-ABI-0-0 %s
 // CHECK-MAMDGPU-DEBUGGER-ABI-0-0: the clang compiler does not support 
'-mamdgpu-debugger-abi=0.0'
 
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri 
-mamdgpu-debugger-abi=1.0 %s -o 2>&1 \
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri 
-mamdgpu-debugger-abi=1.0 %s -o - 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-MAMDGPU-DEBUGGER-ABI-1-0 %s
 // CHECK-MAMDGPU-DEBUGGER-ABI-1-0: "-target-feature" 
"+amdgpu-debugger-insert-nops" "-target-feature" 
"+amdgpu-debugger-reserve-regs" "-target-feature" 
"+amdgpu-debugger-emit-prologue"

Removed: cfe/trunk/test/Driv

r304684 - Implement isDefined by call to isThisDeclarationADefinition.

2017-06-04 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sun Jun  4 07:53:12 2017
New Revision: 304684

URL: http://llvm.org/viewvc/llvm-project?rev=304684&view=rev
Log:
Implement isDefined by call to isThisDeclarationADefinition.

Modifies FunctionDecl::isThisDeclarationADefinition so that it covers
all the cases checked by FunctionDecl::isDefined. Implements the latter
method by call to isThisDeclarationADefinition.

This change is a part of the patch D30170.


Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=304684&r1=304683&r2=304684&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sun Jun  4 07:53:12 2017
@@ -1829,14 +1829,15 @@ public:
 return getBody(Definition);
   }
 
-  /// isThisDeclarationADefinition - Returns whether this specific
-  /// declaration of the function is also a definition. This does not
-  /// determine whether the function has been defined (e.g., in a
-  /// previous definition); for that information, use isDefined. Note
-  /// that this returns false for a defaulted function unless that function
-  /// has been implicitly defined (possibly as deleted).
+  /// Returns whether this specific declaration of the function is also a
+  /// definition that does not contain uninstantiated body.
+  ///
+  /// This does not determine whether the function has been defined (e.g., in a
+  /// previous definition); for that information, use isDefined.
+  ///
   bool isThisDeclarationADefinition() const {
-return IsDeleted || Body || IsLateTemplateParsed;
+return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
+  hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=304684&r1=304683&r2=304684&view=diff
==
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sun Jun  4 07:53:12 2017
@@ -2534,9 +2534,8 @@ bool FunctionDecl::hasTrivialBody() cons
 
 bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
   for (auto I : redecls()) {
-if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed ||
-I->hasDefiningAttr()) {
-  Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
+if (I->isThisDeclarationADefinition()) {
+  Definition = I;
   return true;
 }
   }

Modified: cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp?rev=304684&r1=304683&r2=304684&view=diff
==
--- cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp Sun Jun  4 07:53:12 
2017
@@ -136,13 +136,13 @@ struct bad_decls {
 };
 
 struct DefaultDelete {
-  DefaultDelete() = default; // expected-note {{previous declaration is here}}
+  DefaultDelete() = default; // expected-note {{previous definition is here}}
   DefaultDelete() = delete; // expected-error {{constructor cannot be 
redeclared}}
 
-  ~DefaultDelete() = default; // expected-note {{previous declaration is here}}
+  ~DefaultDelete() = default; // expected-note {{previous definition is here}}
   ~DefaultDelete() = delete; // expected-error {{destructor cannot be 
redeclared}}
 
-  DefaultDelete &operator=(const DefaultDelete &) = default; // expected-note 
{{previous declaration is here}}
+  DefaultDelete &operator=(const DefaultDelete &) = default; // expected-note 
{{previous definition is here}}
   DefaultDelete &operator=(const DefaultDelete &) = delete; // expected-error 
{{class member cannot be redeclared}}
 };
 


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


r304963 - Catch invalid bitwise operation on vector of floats

2017-06-07 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Jun  8 00:25:19 2017
New Revision: 304963

URL: http://llvm.org/viewvc/llvm-project?rev=304963&view=rev
Log:
Catch invalid bitwise operation on vector of floats

Bitwise complement applied to vector of floats described with
attribute `ext_vector_type` is not diagnosed as error. Attempt to
compile such construct causes assertion violation in Instruction.cpp.
With this change the complement is treated similar to the case of
vector type described with attribute `vector_size`.

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

Added:
cfe/trunk/test/Sema/ext_vector_ops.c
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=304963&r1=304962&r2=304963&view=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun  8 00:25:19 2017
@@ -11975,16 +11975,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
   << resultType << Input.get()->getSourceRange();
 else if (resultType->hasIntegerRepresentation())
   break;
-else if (resultType->isExtVectorType()) {
-  if (Context.getLangOpts().OpenCL) {
-// OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate
-// on vector float types.
-QualType T = resultType->getAs()->getElementType();
-if (!T->isIntegerType())
-  return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-   << resultType << Input.get()->getSourceRange());
-  }
-  break;
+else if (resultType->isExtVectorType() && Context.getLangOpts().OpenCL) {
+  // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate
+  // on vector float types.
+  QualType T = resultType->getAs()->getElementType();
+  if (!T->isIntegerType())
+return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+  << resultType << Input.get()->getSourceRange());
 } else {
   return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input.get()->getSourceRange());

Added: cfe/trunk/test/Sema/ext_vector_ops.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ext_vector_ops.c?rev=304963&view=auto
==
--- cfe/trunk/test/Sema/ext_vector_ops.c (added)
+++ cfe/trunk/test/Sema/ext_vector_ops.c Thu Jun  8 00:25:19 2017
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversion -triple 
x86_64-apple-darwin10
+
+typedef unsigned int v2u __attribute__ ((ext_vector_type(2)));
+typedef int v2s __attribute__ ((ext_vector_type(2)));
+typedef float v2f __attribute__ ((ext_vector_type(2)));
+
+void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
+  // Bitwise binary operators
+  (void)(v2ua & v2ua);
+  (void)(v2fa & v2fa); // expected-error{{invalid operands to binary 
expression}}
+
+  // Unary operators
+  (void)(~v2ua);
+  (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 
'float' values) to unary}}
+
+  // Comparison operators
+  v2sa = (v2ua==v2sa);
+
+  // Arrays
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 
'v2u' (vector of 2 'unsigned int' values}}
+  int array2[17];
+  // FIXME: error message below needs type!
+  (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
+
+  v2u *v2u_ptr = 0;
+  v2s *v2s_ptr;
+}


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


r304964 - Improve diagnostics if friend function redefines file-level function.

2017-06-07 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Jun  8 01:07:07 2017
New Revision: 304964

URL: http://llvm.org/viewvc/llvm-project?rev=304964&view=rev
Log:
Improve diagnostics if friend function redefines file-level function.

Clang makes check for function redefinition after it merged the new
declaration with the existing one. As a result, it produces poor
diagnostics in the case of a friend function defined inline, as in
the code:
```
void func() {}
class C { friend void func() {} };
```
Error message in this case states that `inline declaration of 'func'
follows non-inline definition`, which is misleading, as `func` does
not have explicit `inline` specifier.

With this changes compiler reports function redefinition if the new
function is a friend defined inline and it does not have explicit
`inline` specifier.

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

Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=304964&r1=304963&r2=304964&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun  8 01:07:07 2017
@@ -638,7 +638,12 @@ bool Sema::MergeCXXFunctionDecl(Function
 Diag(Old->getLocation(), diag::note_previous_declaration);
 Invalid = true;
   } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() &&
- Old->isDefined(Def)) {
+ Old->isDefined(Def) &&
+ // If a friend function is inlined but does not have 'inline'
+ // specifier, it is a definition. Do not report attribute conflict
+ // in this case, redefinition will be diagnosed later.
+ (New->isInlineSpecified() ||
+  New->getFriendObjectKind() == Decl::FOK_None)) {
 // C++11 [dcl.fcn.spec]p4:
 //   If the definition of a function appears in a translation unit before 
its
 //   first declaration as inline, the program is ill-formed.

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp?rev=304964&r1=304963&r2=304964&view=diff
==
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp Thu Jun  8 01:07:07 
2017
@@ -4,3 +4,31 @@ void f0() { // expected-note {{previous
 }
 
 inline void f0(); // expected-error {{inline declaration of 'f0' follows 
non-inline definition}}
+
+void func_01() {} // expected-note{{previous definition is here}}
+struct C01 {
+  friend void func_01() {} // expected-error{{redefinition of 'func_01'}}
+};
+
+void func_02() {} // expected-note{{previous definition is here}}
+struct C02 {
+  friend inline void func_02(); // expected-error{{inline declaration of 
'func_02' follows non-inline definition}}
+};
+
+void func_03() {} // expected-note{{previous definition is here}}
+struct C03 {
+  friend inline void func_03() {} // expected-error{{inline declaration of 
'func_03' follows non-inline definition}}
+};
+
+void func_04() {} // expected-note{{previous definition is here}}
+inline void func_04() {} // expected-error{{inline declaration of 'func_04' 
follows non-inline definition}}
+
+void func_06() {} // expected-note{{previous definition is here}}
+template struct C06 {
+  friend inline void func_06() {} // expected-error{{inline declaration of 
'func_06' follows non-inline definition}}
+};
+
+void func_07() {} // expected-note{{previous definition is here}}
+template struct C07 {
+  friend inline void func_07(); // expected-error{{inline declaration of 
'func_07' follows non-inline definition}}
+};


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


r304965 - Do not inherit default arguments for friend function in class template.

2017-06-07 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Jun  8 01:31:19 2017
New Revision: 304965

URL: http://llvm.org/viewvc/llvm-project?rev=304965&view=rev
Log:
Do not inherit default arguments for friend function in class template.

A function declared in a friend declaration may have declarations prior
to the containing class definition. If such declaration defines default
argument, the friend function declaration inherits them. This behavior
causes problems if the class where the friend is declared is a template:
during the class instantiation the friend function looks like if it had
default arguments, so error is triggered.

With this change friend functions declared in class templates do not
inherit default arguments. Actual set of them will be defined at the
point where the containing class is instantiated.

This change fixes PR12724.

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

Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=304965&r1=304964&r2=304965&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun  8 01:31:19 2017
@@ -547,17 +547,23 @@ bool Sema::MergeCXXFunctionDecl(Function
   Diag(OldParam->getLocation(), diag::note_previous_definition)
 << OldParam->getDefaultArgRange();
 } else if (OldParamHasDfl) {
-  // Merge the old default argument into the new parameter.
-  // It's important to use getInit() here;  getDefaultArg()
-  // strips off any top-level ExprWithCleanups.
-  NewParam->setHasInheritedDefaultArg();
-  if (OldParam->hasUnparsedDefaultArg())
-NewParam->setUnparsedDefaultArg();
-  else if (OldParam->hasUninstantiatedDefaultArg())
-NewParam->setUninstantiatedDefaultArg(
-  OldParam->getUninstantiatedDefaultArg());
-  else
-NewParam->setDefaultArg(OldParam->getInit());
+  // Merge the old default argument into the new parameter unless the new
+  // function is a friend declaration in a template class. In the latter
+  // case the default arguments will be inherited when the friend
+  // declaration will be instantiated.
+  if (New->getFriendObjectKind() == Decl::FOK_None ||
+  !New->getLexicalDeclContext()->isDependentContext()) {
+// It's important to use getInit() here;  getDefaultArg()
+// strips off any top-level ExprWithCleanups.
+NewParam->setHasInheritedDefaultArg();
+if (OldParam->hasUnparsedDefaultArg())
+  NewParam->setUnparsedDefaultArg();
+else if (OldParam->hasUninstantiatedDefaultArg())
+  NewParam->setUninstantiatedDefaultArg(
+   
OldParam->getUninstantiatedDefaultArg());
+else
+  NewParam->setDefaultArg(OldParam->getInit());
+  }
 } else if (NewParamHasDfl) {
   if (New->getDescribedFunctionTemplate()) {
 // Paragraph 4, quoted above, only applies to non-template functions.

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp?rev=304965&r1=304964&r2=304965&view=diff
==
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp Thu Jun  8 
01:31:19 2017
@@ -73,3 +73,36 @@ void Test ()
 }
 
 } // namespace
+
+namespace pr12724 {
+
+void func_01(bool param = true);
+class C01 {
+public:
+  friend void func_01(bool param);
+};
+
+void func_02(bool param = true);
+template
+class C02 {
+public:
+  friend void func_02(bool param);
+};
+C02 c02;
+
+void func_03(bool param);
+template
+class C03 {
+public:
+  friend void func_03(bool param);
+};
+void func_03(bool param = true);
+C03 c03;
+
+void main() {
+  func_01();
+  func_02();
+  func_03();
+}
+
+} // namespace pr12724


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


Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-13 Thread Serge Pavlov via cfe-commits
I cannot reproduce such fail, so I can only guess how changes made in
https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/rL303741
could cause such problem. Behavior of `Driver::BuildCompilation` is changed
so that it returns null pointer if errors occur during driver argument
parse. It is called in `CompilationDatabase.cpp` from
`stripPositionalArgs`. The call stack at this point is:
stripPositionalArgs
clang::tooling::FixedCompilationDatabase::loadFromCommandLine
clang::tooling::CommonOptionsParser::CommonOptionsParser
clang::tidy::clangTidyMain
main
`FixedCompilationDatabase::loadFromCommandLine` returns null and
CommonOptionsParser uses another method to create compilation database. The
output "Compile command not found" means that no input file were found in
`ClangTool::run`. Maybe some file names are nulls?


Thanks,
--Serge

2017-06-13 3:42 GMT+07:00 David Blaikie :

> I've been seeing errors from this test recently:
>
> Command Output (stderr):
> --
> 1 error generated.
> Error while processing /usr/local/google/home/blaikie/dev/llvm/src/tools/
> clang/tools/extra/test/clang-tidy/diagnostic.cpp.nonexistent.cpp.
> /usr/local/google/home/blaikie/dev/llvm/src/tools/
> clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error: expected
> string not found in input
> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to
> 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
>^
> :2:1: note: scanning from here
> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not
> found.
> ^
> :2:1: note: with expression "@LINE+2" equal to "12"
> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not
> found.
> ^
>
>
> Specifically, the output is:
> $ ./bin/clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor'
> /usr/local/google/home/blaikie/dev/llvm/src/tools/
> clang/tools/extra/test/clang-tidy/diagnostic.cpp -- -fan-unknown-option
> 2>&1error: unknown argument:
> '-fan-unknown-option'
>Skipping /usr/local/google/home/
> blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp.
> Compile command not found.
>
>
> Does this look like it might be related to any of your changes in this
> area? Perhaps the error due to unknown argument is causing clang-tidy not
> to continue on to run the check & report the warning?
>
>
> On Wed, May 24, 2017 at 3:51 AM Serge Pavlov via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Author: sepavloff
>> Date: Wed May 24 05:50:56 2017
>> New Revision: 303735
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev
>> Log:
>> Modify test so that it looks for patterns in stderr as well
>>
>> With the change https://reviews.llvm.org/D33013 driver will not build
>> compilation object if command line is invalid, in particular, if
>> unrecognized option is provided. In such cases it will prints diagnostics
>> on stderr. The test 'clang-tidy/diagnostic.cpp' checks reaction on
>> unrecognized option and will fail when D33013 is applied because it checks
>> only stdout for test patterns and expects the name of diagnostic category
>> prepared by clang-tidy. With this change the test makes more general check
>> and must work in either case.
>>
>> Differential Revision: https://reviews.llvm.org/D33173
>>
>> Modified:
>> clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
>>
>> Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
>> trunk/test/clang-tidy/diagnostic.cpp?rev=303735&r1=
>> 303734&r2=303735&view=diff
>> 
>> ==
>> --- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original)
>> +++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Wed May 24
>> 05:50:56 2017
>> @@ -1,11 +1,11 @@
>>  // RUN: clang-tidy -checks='-*,modernize-use-override'
>> %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1
>> -implicit-check-not='{{warning:|error:}}' %s
>> -// RUN: clang-tidy 
>> -checks='-*,clang-diagnostic-*,google-explicit-constructor'
>> %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2
>> -implicit-check-not='{{warning:|error:}}' %s
>> -// RUN: clang-tidy -che

r305379 - Function with unparsed body is a definition

2017-06-14 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Jun 14 05:07:02 2017
New Revision: 305379

URL: http://llvm.org/viewvc/llvm-project?rev=305379&view=rev
Log:
Function with unparsed body is a definition

While a function body is being parsed, the function declaration is not 
considered
as a definition because it does not have a body yet. In some cases it leads to
incorrect interpretation, the case is presented in
https://bugs.llvm.org/show_bug.cgi?id=14785:
```
template struct Somewhat {
  void internal() const {}
  friend void operator+(int const &, Somewhat const &) {}
};
void operator+(int const &, Somewhat const &x) { x.internal(); }
```
When statement `x.internal()` in the body of global `operator+` is parsed, the 
type
of `x` must be completed, so the instantiation of `Somewhat` is started. 
It
instantiates the declaration of `operator+` defined inline, and makes a check 
for
redefinition. The check does not detect another definition because the 
declaration
of `operator+` is still not defining as does not have a body yet.

To solves this problem the function `isThisDeclarationADefinition` considers
a function declaration as a definition if it has flag `WillHaveBody` set.

This change fixes PR14785.

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

Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/Sema/SemaCUDA.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/friend2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=305379&r1=305378&r2=305379&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Jun 14 05:07:02 2017
@@ -1872,7 +1872,7 @@ public:
   ///
   bool isThisDeclarationADefinition() const {
 return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  hasDefiningAttr();
+  WillHaveBody || hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific

Modified: cfe/trunk/lib/Sema/SemaCUDA.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCUDA.cpp?rev=305379&r1=305378&r2=305379&view=diff
==
--- cfe/trunk/lib/Sema/SemaCUDA.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp Wed Jun 14 05:07:02 2017
@@ -629,12 +629,6 @@ static bool IsKnownEmitted(Sema &S, Func
   // emitted, because (say) the definition could include "inline".
   FunctionDecl *Def = FD->getDefinition();
 
-  // We may currently be parsing the body of FD, in which case
-  // FD->getDefinition() will be null, but we still want to treat FD as though
-  // it's a definition.
-  if (!Def && FD->willHaveBody())
-Def = FD;
-
   if (Def &&
   
!isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
 return true;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=305379&r1=305378&r2=305379&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 14 05:07:02 2017
@@ -12218,6 +12218,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
 
   if (FD) {
 FD->setBody(Body);
+FD->setWillHaveBody(false);
 
 if (getLangOpts().CPlusPlus14) {
   if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() &&

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=305379&r1=305378&r2=305379&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 14 05:07:02 2017
@@ -13878,6 +13878,9 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou
 return;
   }
 
+  // Deleted function does not have a body.
+  Fn->setWillHaveBody(false);
+
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
 // Don't consider the implicit declaration we generate for explicit
 // specializations. FIXME: Do not generate these implicit declarations.

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=305379&r1=305378&r2=305379&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Jun 14 05:07:02 2017
@@ -1782,6 +1782,12 @@ Decl *TemplateDeclInstantiator::VisitFun
   Previous.clear();
   }
 
+  if (isFriend) {
+Function->setObjectOfFriendDecl();
+if (FunctionTemplate)
+  FunctionTemplate->setOb

r305381 - Reverted 305379 (Function with unparsed body is a definition)

2017-06-14 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Jun 14 05:57:56 2017
New Revision: 305381

URL: http://llvm.org/viewvc/llvm-project?rev=305381&view=rev
Log:
Reverted 305379 (Function with unparsed body is a definition)

It broke clang-x86_64-linux-selfhost-modules-2 and some other buildbots.


Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/Sema/SemaCUDA.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/friend2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Jun 14 05:57:56 2017
@@ -1872,7 +1872,7 @@ public:
   ///
   bool isThisDeclarationADefinition() const {
 return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  WillHaveBody || hasDefiningAttr();
+  hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific

Modified: cfe/trunk/lib/Sema/SemaCUDA.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCUDA.cpp?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/lib/Sema/SemaCUDA.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp Wed Jun 14 05:57:56 2017
@@ -629,6 +629,12 @@ static bool IsKnownEmitted(Sema &S, Func
   // emitted, because (say) the definition could include "inline".
   FunctionDecl *Def = FD->getDefinition();
 
+  // We may currently be parsing the body of FD, in which case
+  // FD->getDefinition() will be null, but we still want to treat FD as though
+  // it's a definition.
+  if (!Def && FD->willHaveBody())
+Def = FD;
+
   if (Def &&
   
!isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
 return true;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 14 05:57:56 2017
@@ -12218,7 +12218,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
 
   if (FD) {
 FD->setBody(Body);
-FD->setWillHaveBody(false);
 
 if (getLangOpts().CPlusPlus14) {
   if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() &&

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 14 05:57:56 2017
@@ -13878,9 +13878,6 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou
 return;
   }
 
-  // Deleted function does not have a body.
-  Fn->setWillHaveBody(false);
-
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
 // Don't consider the implicit declaration we generate for explicit
 // specializations. FIXME: Do not generate these implicit declarations.

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Jun 14 05:57:56 2017
@@ -1782,12 +1782,6 @@ Decl *TemplateDeclInstantiator::VisitFun
   Previous.clear();
   }
 
-  if (isFriend) {
-Function->setObjectOfFriendDecl();
-if (FunctionTemplate)
-  FunctionTemplate->setObjectOfFriendDecl();
-  }
-
   SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous,
isExplicitSpecialization);
 
@@ -1798,6 +1792,7 @@ Decl *TemplateDeclInstantiator::VisitFun
   // If the original function was part of a friend declaration,
   // inherit its namespace state and add it to the owner.
   if (isFriend) {
+PrincipalDecl->setObjectOfFriendDecl();
 DC->makeDeclVisibleInContext(PrincipalDecl);
 
 bool QueuedInstantiation = false;

Modified: cfe/trunk/test/SemaCXX/friend2.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/friend2.cpp?rev=305381&r1=305380&r2=305381&view=diff
==
--- cfe/trunk/test/SemaCXX/friend2.cpp (original)
+++ cfe/trunk/test/SemaCXX/friend2.cpp Wed Jun 14 05:57:56 2017
@@ -170,15 +170,3 @@ struct Test {
 template class Test;
 
 }
-
-namespace pr14785 {
-template
-struct Somewhat {
-  void internal() co

Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-14 Thread Serge Pavlov via cfe-commits
2017-06-14 4:24 GMT+07:00 David Blaikie :

> Ah, I find that the test passes if I remove the compile_commands.json file
> from my build directory (I have Ninja configured to generate a
> compile_commands.json file).
>
> Looks like what happens is it finds the compilation database and fails
> hard when the database doesn't contain a compile command for the file in
> question. If the database is not found, it falls back to some basic command
> behavior, perhaps?
>
>
You are right, constructor of `CommonOptionsParser` calls
`autoDetectFromSource` or `autoDetectFromDirectory` prior to final
construction of `FixedCompilationDatabase.

Is there some way this test could be fixed to cope with this, otherwise it
> seems to get in the way of people actually using clang tools in their
> LLVM/Clang build environment?
>
>
IIUC, presence of stale compilation database file in test directory could
break many tests. I don't understand why only diagnostic.cpp fails,
probably there is something wrong with the clang-tidy application cleanup
in this case?


> On Tue, Jun 13, 2017 at 7:41 AM Serge Pavlov  wrote:
>
>> I cannot reproduce such fail, so I can only guess how changes made in
>> https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/rL303741
>> could cause such problem. Behavior of `Driver::BuildCompilation` is changed
>> so that it returns null pointer if errors occur during driver argument
>> parse. It is called in `CompilationDatabase.cpp` from
>> `stripPositionalArgs`. The call stack at this point is:
>> stripPositionalArgs
>> clang::tooling::FixedCompilationDatabase::loadFromCommandLine
>> clang::tooling::CommonOptionsParser::CommonOptionsParser
>> clang::tidy::clangTidyMain
>> main
>> `FixedCompilationDatabase::loadFromCommandLine` returns null and
>> CommonOptionsParser uses another method to create compilation database. The
>> output "Compile command not found" means that no input file were found in
>> `ClangTool::run`. Maybe some file names are nulls?
>>
>>
>> Thanks,
>> --Serge
>>
>> 2017-06-13 3:42 GMT+07:00 David Blaikie :
>>
>>> I've been seeing errors from this test recently:
>>>
>>> Command Output (stderr):
>>> --
>>> 1 error generated.
>>> Error while processing /usr/local/google/home/blaikie
>>> /dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/
>>> diagnostic.cpp.nonexistent.cpp.
>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/
>>> tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error: expected
>>> string not found in input
>>> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to
>>> 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
>>>^
>>> :2:1: note: scanning from here
>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/
>>> tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not found.
>>> ^
>>> :2:1: note: with expression "@LINE+2" equal to "12"
>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/
>>> tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not found.
>>> ^
>>>
>>>
>>> Specifically, the output is:
>>> $ ./bin/clang-tidy 
>>> -checks='-*,clang-diagnostic-*,google-explicit-constructor'
>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/
>>> tools/extra/test/clang-tidy/diagnostic.cpp -- -fan-unknown-option 2>&1
>>>    error: unknown argument: '-fan-unknown-option'
>>>
>>>Skipping /usr/local/google/home/blaikie
>>> /dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp.
>>> Compile command not found.
>>>
>>>
>>> Does this look like it might be related to any of your changes in this
>>> area? Perhaps the error due to unknown argument is causing clang-tidy not
>>> to continue on to run the check & report the warning?
>>>
>>>
>>> On Wed, May 24, 2017 at 3:51 AM Serge Pavlov via cfe-commits <
>>> cfe-commits@lists.llvm.org> wrote:
>>>
>>>> Author: sepavloff
>>>> Date: Wed May 24 05:50:56 2017
>>>> New Revision: 303735
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev
>>>> Log:
>>>> Modify test so that it looks for patterns in stderr as well
>>>>
>>>> With the change https://reviews.llvm.org/D33013 driver w

Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-15 Thread Serge Pavlov via cfe-commits
2017-06-15 2:43 GMT+07:00 David Blaikie :

>
>
> On Wed, Jun 14, 2017, 8:17 AM Serge Pavlov  wrote:
>
>> 2017-06-14 4:24 GMT+07:00 David Blaikie :
>>
>>> Ah, I find that the test passes if I remove the compile_commands.json
>>> file from my build directory (I have Ninja configured to generate a
>>> compile_commands.json file).
>>>
>>> Looks like what happens is it finds the compilation database and fails
>>> hard when the database doesn't contain a compile command for the file in
>>> question. If the database is not found, it falls back to some basic command
>>> behavior, perhaps?
>>>
>>>
>> You are right, constructor of `CommonOptionsParser` calls
>> `autoDetectFromSource` or `autoDetectFromDirectory` prior to final
>> construction of `FixedCompilationDatabase.
>>
>> Is there some way this test could be fixed to cope with this, otherwise
>>> it seems to get in the way of people actually using clang tools in their
>>> LLVM/Clang build environment?
>>>
>>>
>> IIUC, presence of stale compilation database file in test directory could
>> break many tests. I don't understand why only diagnostic.cpp fails,
>> probably there is something wrong with the clang-tidy application cleanup
>> in this case?
>>
>
> Except it's neither stale nor in the test directory.
>
> It's the up to date/useful/used compile_commands.json generated by ninja
> in the root of the build tree.
>

I miss something. If I could reproduce the problem, I would investigate it.


>
>
>>
>>> On Tue, Jun 13, 2017 at 7:41 AM Serge Pavlov 
>>> wrote:
>>>
>>>> I cannot reproduce such fail, so I can only guess how changes made in
>>>> https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/rL303741
>>>> could cause such problem. Behavior of `Driver::BuildCompilation` is changed
>>>> so that it returns null pointer if errors occur during driver argument
>>>> parse. It is called in `CompilationDatabase.cpp` from
>>>> `stripPositionalArgs`. The call stack at this point is:
>>>> stripPositionalArgs
>>>> clang::tooling::FixedCompilationDatabase::loadFromCommandLine
>>>> clang::tooling::CommonOptionsParser::CommonOptionsParser
>>>> clang::tidy::clangTidyMain
>>>> main
>>>> `FixedCompilationDatabase::loadFromCommandLine` returns null and
>>>> CommonOptionsParser uses another method to create compilation database. The
>>>> output "Compile command not found" means that no input file were found in
>>>> `ClangTool::run`. Maybe some file names are nulls?
>>>>
>>>>
>>>> Thanks,
>>>> --Serge
>>>>
>>>> 2017-06-13 3:42 GMT+07:00 David Blaikie :
>>>>
>>>>> I've been seeing errors from this test recently:
>>>>>
>>>>> Command Output (stderr):
>>>>> --
>>>>> 1 error generated.
>>>>> Error while processing /usr/local/google/home/
>>>>> blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-
>>>>> tidy/diagnostic.cpp.nonexistent.cpp.
>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error:
>>>>> expected string not found in input
>>>>> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double'
>>>>> to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-
>>>>> conversion]
>>>>>^
>>>>> :2:1: note: scanning from here
>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not
>>>>> found.
>>>>> ^
>>>>> :2:1: note: with expression "@LINE+2" equal to "12"
>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not
>>>>> found.
>>>>> ^
>>>>>
>>>>>
>>>>> Specifically, the output is:
>>>>> $ ./bin/clang-tidy 
>>>>> -checks='-*,clang-diagnostic-*,google-explicit-constructor'
>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp --
>>>>> -fan-unknown-option 2>&

r305903 - Function with unparsed body is a definition

2017-06-21 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Jun 21 07:46:57 2017
New Revision: 305903

URL: http://llvm.org/viewvc/llvm-project?rev=305903&view=rev
Log:
Function with unparsed body is a definition

While a function body is being parsed, the function declaration is not 
considered
as a definition because it does not have a body yet. In some cases it leads to
incorrect interpretation, the case is presented in
https://bugs.llvm.org/show_bug.cgi?id=14785:
```
template struct Somewhat {
  void internal() const {}
  friend void operator+(int const &, Somewhat const &) {}
};
void operator+(int const &, Somewhat const &x) { x.internal(); }
```
When statement `x.internal()` in the body of global `operator+` is parsed, the 
type
of `x` must be completed, so the instantiation of `Somewhat` is started. 
It
instantiates the declaration of `operator+` defined inline, and makes a check 
for
redefinition. The check does not detect another definition because the 
declaration
of `operator+` is still not defining as does not have a body yet.

To solves this problem the function `isThisDeclarationADefinition` considers
a function declaration as a definition if it has flag `WillHaveBody` set.

This change fixes PR14785.

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

This is a recommit of 305379, reverted in 305381, with small changes.

Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/Sema/SemaCUDA.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/friend2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=305903&r1=305902&r2=305903&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Jun 21 07:46:57 2017
@@ -1874,7 +1874,7 @@ public:
   ///
   bool isThisDeclarationADefinition() const {
 return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  hasDefiningAttr();
+  WillHaveBody || hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific

Modified: cfe/trunk/lib/Sema/SemaCUDA.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCUDA.cpp?rev=305903&r1=305902&r2=305903&view=diff
==
--- cfe/trunk/lib/Sema/SemaCUDA.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp Wed Jun 21 07:46:57 2017
@@ -629,12 +629,6 @@ static bool IsKnownEmitted(Sema &S, Func
   // emitted, because (say) the definition could include "inline".
   FunctionDecl *Def = FD->getDefinition();
 
-  // We may currently be parsing the body of FD, in which case
-  // FD->getDefinition() will be null, but we still want to treat FD as though
-  // it's a definition.
-  if (!Def && FD->willHaveBody())
-Def = FD;
-
   if (Def &&
   
!isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
 return true;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=305903&r1=305902&r2=305903&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 21 07:46:57 2017
@@ -12232,6 +12232,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
 
   if (FD) {
 FD->setBody(Body);
+FD->setWillHaveBody(false);
 
 if (getLangOpts().CPlusPlus14) {
   if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() &&

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=305903&r1=305902&r2=305903&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 21 07:46:57 2017
@@ -13878,6 +13878,9 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou
 return;
   }
 
+  // Deleted function does not have a body.
+  Fn->setWillHaveBody(false);
+
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
 // Don't consider the implicit declaration we generate for explicit
 // specializations. FIXME: Do not generate these implicit declarations.

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=305903&r1=305902&r2=305903&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Jun 21 07:46:57 2017
@@ -1782,6 +1782,9 @@ Decl *TemplateDeclInstantiator::VisitFun
   Previous.clear();
   }
 
+  if (isFriend)
+Function->setObjectOfFri

Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-24 Thread Serge Pavlov via cfe-commits
;>>>>>> output "Compile command not found" means that no input file were found 
>>>>>>> in
>>>>>>> `ClangTool::run`. Maybe some file names are nulls?
>>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> --Serge
>>>>>>>
>>>>>>> 2017-06-13 3:42 GMT+07:00 David Blaikie :
>>>>>>>
>>>>>>>> I've been seeing errors from this test recently:
>>>>>>>>
>>>>>>>> Command Output (stderr):
>>>>>>>> --
>>>>>>>> 1 error generated.
>>>>>>>> Error while processing /usr/local/google/home/
>>>>>>>> blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-
>>>>>>>> tidy/diagnostic.cpp.nonexistent.cpp.
>>>>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error:
>>>>>>>> expected string not found in input
>>>>>>>> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from
>>>>>>>> 'double' to 'int' changes value from 1.5 to 1 
>>>>>>>> [clang-diagnostic-literal-
>>>>>>>> conversion]
>>>>>>>>^
>>>>>>>> :2:1: note: scanning from here
>>>>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command
>>>>>>>> not found.
>>>>>>>> ^
>>>>>>>> :2:1: note: with expression "@LINE+2" equal to "12"
>>>>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command
>>>>>>>> not found.
>>>>>>>> ^
>>>>>>>>
>>>>>>>>
>>>>>>>> Specifically, the output is:
>>>>>>>> $ ./bin/clang-tidy 
>>>>>>>> -checks='-*,clang-diagnostic-*,google-explicit-constructor'
>>>>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp --
>>>>>>>> -fan-unknown-option 2>&1error: unknown
>>>>>>>> argument: '-fan-unknown-option'
>>>>>>>>  Skipping
>>>>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command
>>>>>>>> not found.
>>>>>>>>
>>>>>>>>
>>>>>>>> Does this look like it might be related to any of your changes in
>>>>>>>> this area? Perhaps the error due to unknown argument is causing 
>>>>>>>> clang-tidy
>>>>>>>> not to continue on to run the check & report the warning?
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, May 24, 2017 at 3:51 AM Serge Pavlov via cfe-commits <
>>>>>>>> cfe-commits@lists.llvm.org> wrote:
>>>>>>>>
>>>>>>>>> Author: sepavloff
>>>>>>>>> Date: Wed May 24 05:50:56 2017
>>>>>>>>> New Revision: 303735
>>>>>>>>>
>>>>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev
>>>>>>>>> Log:
>>>>>>>>> Modify test so that it looks for patterns in stderr as well
>>>>>>>>>
>>>>>>>>> With the change https://reviews.llvm.org/D33013 driver will not
>>>>>>>>> build
>>>>>>>>> compilation object if command line is invalid, in particular, if
>>>>>>>>> unrecognized option is provided. In such cases it will prints
>>>>>>>>> diagnostics
>>>>>>>>> on stderr. The test 'clang-tidy/diagnostic.cpp' checks reaction on
>>>>>>>>> unrecognized option and will fail when D3

Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-25 Thread Serge Pavlov via cfe-commits
n test directory
>>>>>>> could break many tests. I don't understand why only diagnostic.cpp 
>>>>>>> fails,
>>>>>>> probably there is something wrong with the clang-tidy application 
>>>>>>> cleanup
>>>>>>> in this case?
>>>>>>>
>>>>>>
>>>>>> Except it's neither stale nor in the test directory.
>>>>>>
>>>>>> It's the up to date/useful/used compile_commands.json generated by
>>>>>> ninja in the root of the build tree.
>>>>>>
>>>>>
>>>>> I miss something. If I could reproduce the problem, I would
>>>>> investigate it.
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>> On Tue, Jun 13, 2017 at 7:41 AM Serge Pavlov 
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> I cannot reproduce such fail, so I can only guess how changes made
>>>>>>>>> in https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/
>>>>>>>>> rL303741 could cause such problem. Behavior of
>>>>>>>>> `Driver::BuildCompilation` is changed so that it returns null pointer 
>>>>>>>>> if
>>>>>>>>> errors occur during driver argument parse. It is called in
>>>>>>>>> `CompilationDatabase.cpp` from `stripPositionalArgs`. The call stack 
>>>>>>>>> at
>>>>>>>>> this point is:
>>>>>>>>> stripPositionalArgs
>>>>>>>>> clang::tooling::FixedCompilationDatabase::loadFromCommandLine
>>>>>>>>> clang::tooling::CommonOptionsParser::CommonOptionsParser
>>>>>>>>> clang::tidy::clangTidyMain
>>>>>>>>> main
>>>>>>>>> `FixedCompilationDatabase::loadFromCommandLine` returns null and
>>>>>>>>> CommonOptionsParser uses another method to create compilation 
>>>>>>>>> database. The
>>>>>>>>> output "Compile command not found" means that no input file were 
>>>>>>>>> found in
>>>>>>>>> `ClangTool::run`. Maybe some file names are nulls?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> --Serge
>>>>>>>>>
>>>>>>>>> 2017-06-13 3:42 GMT+07:00 David Blaikie :
>>>>>>>>>
>>>>>>>>>> I've been seeing errors from this test recently:
>>>>>>>>>>
>>>>>>>>>> Command Output (stderr):
>>>>>>>>>> --
>>>>>>>>>> 1 error generated.
>>>>>>>>>> Error while processing /usr/local/google/home/
>>>>>>>>>> blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-
>>>>>>>>>> tidy/diagnostic.cpp.nonexistent.cpp.
>>>>>>>>>> /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error:
>>>>>>>>>> expected string not found in input
>>>>>>>>>> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from
>>>>>>>>>> 'double' to 'int' changes value from 1.5 to 1 
>>>>>>>>>> [clang-diagnostic-literal-
>>>>>>>>>> conversion]
>>>>>>>>>>^
>>>>>>>>>> :2:1: note: scanning from here
>>>>>>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile
>>>>>>>>>> command not found.
>>>>>>>>>> ^
>>>>>>>>>> :2:1: note: with expression "@LINE+2" equal to "12"
>>>>>>>>>> Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/
>>>>>>>>>> clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile
>>>>>>>>>> command not found.
>>>>>>>>>> ^
&

Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well

2017-06-26 Thread Serge Pavlov via cfe-commits
>>>>> Ah, I find that the test passes if I remove the
>>>>>>>>>> compile_commands.json file from my build directory (I have Ninja 
>>>>>>>>>> configured
>>>>>>>>>> to generate a compile_commands.json file).
>>>>>>>>>>
>>>>>>>>>> Looks like what happens is it finds the compilation database and
>>>>>>>>>> fails hard when the database doesn't contain a compile command for 
>>>>>>>>>> the file
>>>>>>>>>> in question. If the database is not found, it falls back to some 
>>>>>>>>>> basic
>>>>>>>>>> command behavior, perhaps?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> You are right, constructor of `CommonOptionsParser` calls
>>>>>>>>> `autoDetectFromSource` or `autoDetectFromDirectory` prior to final
>>>>>>>>> construction of `FixedCompilationDatabase.
>>>>>>>>>
>>>>>>>>> Is there some way this test could be fixed to cope with this,
>>>>>>>>>> otherwise it seems to get in the way of people actually using clang 
>>>>>>>>>> tools
>>>>>>>>>> in their LLVM/Clang build environment?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> IIUC, presence of stale compilation database file in test
>>>>>>>>> directory could break many tests. I don't understand why only
>>>>>>>>> diagnostic.cpp fails, probably there is something wrong with the 
>>>>>>>>> clang-tidy
>>>>>>>>> application cleanup in this case?
>>>>>>>>>
>>>>>>>>
>>>>>>>> Except it's neither stale nor in the test directory.
>>>>>>>>
>>>>>>>> It's the up to date/useful/used compile_commands.json generated by
>>>>>>>> ninja in the root of the build tree.
>>>>>>>>
>>>>>>>
>>>>>>> I miss something. If I could reproduce the problem, I would
>>>>>>> investigate it.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>>> On Tue, Jun 13, 2017 at 7:41 AM Serge Pavlov 
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> I cannot reproduce such fail, so I can only guess how changes
>>>>>>>>>>> made in https://reviews.llvm.org/rL303756 and
>>>>>>>>>>> https://reviews.llvm.org/rL303741 could cause such problem.
>>>>>>>>>>> Behavior of `Driver::BuildCompilation` is changed so that it 
>>>>>>>>>>> returns null
>>>>>>>>>>> pointer if errors occur during driver argument parse. It is called 
>>>>>>>>>>> in
>>>>>>>>>>> `CompilationDatabase.cpp` from `stripPositionalArgs`. The call 
>>>>>>>>>>> stack at
>>>>>>>>>>> this point is:
>>>>>>>>>>> stripPositionalArgs
>>>>>>>>>>> clang::tooling::FixedCompilationDatabase::loadFromCommandLine
>>>>>>>>>>> clang::tooling::CommonOptionsParser::CommonOptionsParser
>>>>>>>>>>> clang::tidy::clangTidyMain
>>>>>>>>>>> main
>>>>>>>>>>> `FixedCompilationDatabase::loadFromCommandLine` returns null
>>>>>>>>>>> and CommonOptionsParser uses another method to create compilation 
>>>>>>>>>>> database.
>>>>>>>>>>> The output "Compile command not found" means that no input file 
>>>>>>>>>>> were found
>>>>>>>>>>> in `ClangTool::run`. Maybe some file names are nulls?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> --Serge
>>>>>>

r321360 - Unit tests for TBAA metadata generation.

2017-12-22 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Fri Dec 22 07:22:45 2017
New Revision: 321360

URL: http://llvm.org/viewvc/llvm-project?rev=321360&view=rev
Log:
Unit tests for TBAA metadata generation.

Now tests for metadata created by clang involve compiling code snippets
placed into c/c++ source files and matching interesting patterns in the
obtained textual representation of IR. Writting such tests is a painful
process as metadata often form complex tree-like structures but textual
representation of IR contains only a pile of metadata at the module end.

This change implements IR matchers that may be used to match required
patterns in the binary IR representation. In this case the metadata
structure is not broken and creation of match patterns is easier.

The change adds unit tests for TBAA metadata generation.

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

Added:
cfe/trunk/unittests/CodeGen/IRMatchers.h
cfe/trunk/unittests/CodeGen/TBAAMetadataTest.cpp
Modified:
cfe/trunk/unittests/CodeGen/CMakeLists.txt

Modified: cfe/trunk/unittests/CodeGen/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/CodeGen/CMakeLists.txt?rev=321360&r1=321359&r2=321360&view=diff
==
--- cfe/trunk/unittests/CodeGen/CMakeLists.txt (original)
+++ cfe/trunk/unittests/CodeGen/CMakeLists.txt Fri Dec 22 07:22:45 2017
@@ -7,6 +7,7 @@ add_clang_unittest(ClangCodeGenTests
   BufferSourceTest.cpp
   CodeGenExternalTest.cpp
   IncrementalProcessingTest.cpp
+  TBAAMetadataTest.cpp
   )
 
 target_link_libraries(ClangCodeGenTests

Added: cfe/trunk/unittests/CodeGen/IRMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/CodeGen/IRMatchers.h?rev=321360&view=auto
==
--- cfe/trunk/unittests/CodeGen/IRMatchers.h (added)
+++ cfe/trunk/unittests/CodeGen/IRMatchers.h Fri Dec 22 07:22:45 2017
@@ -0,0 +1,453 @@
+//=== unittests/CodeGen/IRMatchers.h - Match on the LLVM IR -*- C++ 
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+/// \file
+/// This file provides a simple mechanism for performing search operations over
+/// IR including metadata and types. It allows writing complex search patterns
+/// using understandable syntax. For instance, the code:
+///
+/// \code
+///   const BasicBlock *BB = ...
+///   const Instruction *I = match(BB,
+///   MInstruction(Instruction::Store,
+///   MConstInt(4, 8),
+///   MMTuple(
+///   MMTuple(
+///   MMString("omnipotent char"),
+///   MMTuple(
+///   MMString("Simple C/C++ TBAA")),
+///   MConstInt(0, 64)),
+///   MSameAs(0),
+///   MConstInt(0;
+/// \endcode
+///
+/// searches the basic block BB for the 'store' instruction, first argument of
+/// which is 'i8 4', and the attached metadata has an item described by the
+/// given tree.
+//===--===//
+
+#ifndef CLANG_UNITTESTS_CODEGEN_IRMATCHERS_H
+#define CLANG_UNITTESTS_CODEGEN_IRMATCHERS_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+
+/// Keeps information about pending match queries.
+///
+/// This class stores state of all unfinished match actions. It allows to
+/// use queries like "this operand is the same as n-th operand", which are
+/// hard to implement otherwise.
+///
+class MatcherContext {
+public:
+
+  /// Describes pending match query.
+  ///
+  /// The query is represented by the current entity being investigated (type,
+  /// value or metadata). If the entity is a member of a list (like arguments),
+  /// the query also keeps the entity number in that list.
+  ///
+  class Query {
+PointerUnion3 Entity;
+unsigned OperandNo;
+
+  public:
+Query(const Value *V, unsigned N) : Entity(V), OperandNo(N) {}
+Query(const Metadata *M, unsigned N) : Entity(M), OperandNo(N) {}
+Query(const Type *T, unsigned N) : Entity(T), OperandNo(N) {}
+
+template
+const T *get() const {
+  return Entity.dyn_cast();
+}
+
+unsigned getOperandNo() const { return OperandNo; }
+  };
+
+  template
+  void push(const T *V, unsigned N = ~0) {
+MatchStack.push_back(Query(V, N));
+  }
+
+  void pop() { MatchStack.pop_back(); }
+
+  template
+  const T *top() const { return MatchStack.back().get(); }
+
+  size_t size() const { return MatchStack.size(); }
+
+  unsigned getOperandNo() const { return MatchStack

r321587 - Enable configuration files in clang

2017-12-30 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sat Dec 30 09:59:26 2017
New Revision: 321587

URL: http://llvm.org/viewvc/llvm-project?rev=321587&view=rev
Log:
Enable configuration files in clang

Clang is inherently a cross compiler and can generate code for any target
enabled during build. It however requires to specify many parameters in the
invocation, which could be hardcoded during configuration process in the
case of single-target compiler. The purpose of configuration files is to
make specifying clang arguments easier.

A configuration file is a collection of driver options, which are inserted
into command line before other options specified in the clang invocation.
It groups related options together and allows specifying them in simpler,
more flexible and less error prone way than just listing the options
somewhere in build scripts. Configuration file may be thought as a "macro"
that names an option set and is expanded when the driver is called.

Use of configuration files is described in `UserManual.rst`.

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

Added:
cfe/trunk/test/Driver/Inputs/config/
cfe/trunk/test/Driver/Inputs/config-1.cfg
cfe/trunk/test/Driver/Inputs/config-2.cfg
cfe/trunk/test/Driver/Inputs/config-2a.cfg
cfe/trunk/test/Driver/Inputs/config-3.cfg
cfe/trunk/test/Driver/Inputs/config-4.cfg
cfe/trunk/test/Driver/Inputs/config-5.cfg
cfe/trunk/test/Driver/Inputs/config-6.cfg
cfe/trunk/test/Driver/Inputs/config/config-4.cfg
cfe/trunk/test/Driver/Inputs/config/i386-qqq.cfg
cfe/trunk/test/Driver/Inputs/config/i386-qqq3.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64-qqq.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64-qqq2.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64.cfg
cfe/trunk/test/Driver/Inputs/config2/
cfe/trunk/test/Driver/Inputs/config2/config-4.cfg
cfe/trunk/test/Driver/Inputs/config2/i386.cfg
cfe/trunk/test/Driver/config-file-errs.c
cfe/trunk/test/Driver/config-file.c
cfe/trunk/test/Driver/config-file2.c
cfe/trunk/test/Driver/config-file3.c
Modified:
cfe/trunk/docs/UsersManual.rst
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Config/config.h.cmake
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/Driver/Driver.cpp

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=321587&r1=321586&r2=321587&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Sat Dec 30 09:59:26 2017
@@ -694,6 +694,77 @@ a special character, which is the conven
 option tells Clang to put double-quotes around the entire filename, which
 is the convention used by NMake and Jom.
 
+Configuration files
+---
+
+Configuration files group command-line options and allow all of them to be
+specified just by referencing the configuration file. They may be used, for
+example, to collect options required to tune compilation for particular
+target, such as -L, -I, -l, --sysroot, codegen options, etc.
+
+The command line option `--config` can be used to specify configuration
+file in a Clang invocation. For example:
+
+::
+
+clang --config /home/user/cfgs/testing.txt
+clang --config debug.cfg
+
+If the provided argument contains a directory separator, it is considered as
+a file path, and options are read from that file. Otherwise the argument is
+treated as a file name and is searched for sequentially in the directories:
+- user directory,
+- system directory,
+- the directory where Clang executable resides.
+Both user and system directories for configuration files are specified during
+clang build using CMake parameters, CLANG_CONFIG_FILE_USER_DIR and
+CLANG_CONFIG_FILE_SYSTEM_DIR respectively. The first file found is used. It is
+an error if the required file cannot be found.
+
+Another way to specify a configuration file is to encode it in executable name.
+For example, if the Clang executable is named `armv7l-clang` (it may be a
+symbolic link to `clang`), then Clang will search for file `armv7l.cfg` in the
+directory where Clang resides.
+
+If a driver mode is specified in invocation, Clang tries to find a file 
specific
+for the specified mode. For example, if the executable file is named
+`x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not 
found,
+looks for `x86_64.cfg'.
+
+If the command line contains options that effectively change target 
architecture
+(these are -m32, -EL, and some others) and the configuration file starts with 
an
+architecture name, Clang tries to load the configuration file for the effective
+architecture. For example, invocation:
+
+::
+
+x86_64-clang -m32 abc.c
+
+causes Clang search for a file `i368.cfg` first, and if no such file is found,
+Clang looks for the file `x86_64.cfg`.

r321588 - Reverted 321587: Enable configuration files in clang

2017-12-30 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sat Dec 30 10:38:44 2017
New Revision: 321588

URL: http://llvm.org/viewvc/llvm-project?rev=321588&view=rev
Log:
Reverted 321587: Enable configuration files in clang

Need to check targets in tests more carefully.


Removed:
cfe/trunk/test/Driver/Inputs/config/
cfe/trunk/test/Driver/Inputs/config-1.cfg
cfe/trunk/test/Driver/Inputs/config-2.cfg
cfe/trunk/test/Driver/Inputs/config-2a.cfg
cfe/trunk/test/Driver/Inputs/config-3.cfg
cfe/trunk/test/Driver/Inputs/config-4.cfg
cfe/trunk/test/Driver/Inputs/config-5.cfg
cfe/trunk/test/Driver/Inputs/config-6.cfg
cfe/trunk/test/Driver/Inputs/config2/
cfe/trunk/test/Driver/config-file-errs.c
cfe/trunk/test/Driver/config-file.c
cfe/trunk/test/Driver/config-file2.c
cfe/trunk/test/Driver/config-file3.c
Modified:
cfe/trunk/docs/UsersManual.rst
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Config/config.h.cmake
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/Driver/Driver.cpp

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=321588&r1=321587&r2=321588&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Sat Dec 30 10:38:44 2017
@@ -694,77 +694,6 @@ a special character, which is the conven
 option tells Clang to put double-quotes around the entire filename, which
 is the convention used by NMake and Jom.
 
-Configuration files

-
-Configuration files group command-line options and allow all of them to be
-specified just by referencing the configuration file. They may be used, for
-example, to collect options required to tune compilation for particular
-target, such as -L, -I, -l, --sysroot, codegen options, etc.
-
-The command line option `--config` can be used to specify configuration
-file in a Clang invocation. For example:
-
-::
-
-clang --config /home/user/cfgs/testing.txt
-clang --config debug.cfg
-
-If the provided argument contains a directory separator, it is considered as
-a file path, and options are read from that file. Otherwise the argument is
-treated as a file name and is searched for sequentially in the directories:
-- user directory,
-- system directory,
-- the directory where Clang executable resides.
-Both user and system directories for configuration files are specified during
-clang build using CMake parameters, CLANG_CONFIG_FILE_USER_DIR and
-CLANG_CONFIG_FILE_SYSTEM_DIR respectively. The first file found is used. It is
-an error if the required file cannot be found.
-
-Another way to specify a configuration file is to encode it in executable name.
-For example, if the Clang executable is named `armv7l-clang` (it may be a
-symbolic link to `clang`), then Clang will search for file `armv7l.cfg` in the
-directory where Clang resides.
-
-If a driver mode is specified in invocation, Clang tries to find a file 
specific
-for the specified mode. For example, if the executable file is named
-`x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not 
found,
-looks for `x86_64.cfg'.
-
-If the command line contains options that effectively change target 
architecture
-(these are -m32, -EL, and some others) and the configuration file starts with 
an
-architecture name, Clang tries to load the configuration file for the effective
-architecture. For example, invocation:
-
-::
-
-x86_64-clang -m32 abc.c
-
-causes Clang search for a file `i368.cfg` first, and if no such file is found,
-Clang looks for the file `x86_64.cfg`.
-
-The configuration file consists of command-line options specified on one or
-more lines. Lines composed of whitespace characters only are ignored as well as
-lines in which the first non-blank character is `#`. Long options may be split
-between several lines by a trailing backslash. Here is example of a
-configuration file:
-
-::
-
-# Several options on line
--c --target=x86_64-unknown-linux-gnu
-
-# Long option split between lines
--I/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../\
-include/c++/5.4.0
-
-# other config files may be included
-@linux.options
-
-Files included by `@file` directives in configuration files are resolved
-relative to the including file. For example, if a configuration file
-`~/.llvm/target.cfg` contains the directive `@os/linux.opts`, the file
-`linux.opts` is searched for in the directory `~/.llvm/os`.
 
 Language and Target-Independent Features
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=321588&r1=321587&r2=321588&view=diff
==
--- c

r321621 - Enable configuration files in clang

2018-01-01 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Mon Jan  1 05:27:01 2018
New Revision: 321621

URL: http://llvm.org/viewvc/llvm-project?rev=321621&view=rev
Log:
Enable configuration files in clang

Clang is inherently a cross compiler and can generate code for any target
enabled during build. It however requires to specify many parameters in the
invocation, which could be hardcoded during configuration process in the
case of single-target compiler. The purpose of configuration files is to
make specifying clang arguments easier.

A configuration file is a collection of driver options, which are inserted
into command line before other options specified in the clang invocation.
It groups related options together and allows specifying them in simpler,
more flexible and less error prone way than just listing the options
somewhere in build scripts. Configuration file may be thought as a "macro"
that names an option set and is expanded when the driver is called.

Use of configuration files is described in `UserManual.rst`.

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

Added:
cfe/trunk/test/Driver/Inputs/config/
cfe/trunk/test/Driver/Inputs/config-1.cfg
cfe/trunk/test/Driver/Inputs/config-2.cfg
cfe/trunk/test/Driver/Inputs/config-2a.cfg
cfe/trunk/test/Driver/Inputs/config-3.cfg
cfe/trunk/test/Driver/Inputs/config-4.cfg
cfe/trunk/test/Driver/Inputs/config-5.cfg
cfe/trunk/test/Driver/Inputs/config-6.cfg
cfe/trunk/test/Driver/Inputs/config/config-4.cfg
cfe/trunk/test/Driver/Inputs/config/i386-qqq.cfg
cfe/trunk/test/Driver/Inputs/config/i386-qqq3.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64-qqq.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64-qqq2.cfg
cfe/trunk/test/Driver/Inputs/config/x86_64.cfg
cfe/trunk/test/Driver/Inputs/config2/
cfe/trunk/test/Driver/Inputs/config2/config-4.cfg
cfe/trunk/test/Driver/Inputs/config2/i386.cfg
cfe/trunk/test/Driver/config-file-errs.c
cfe/trunk/test/Driver/config-file.c
cfe/trunk/test/Driver/config-file2.c
cfe/trunk/test/Driver/config-file3.c
Modified:
cfe/trunk/docs/UsersManual.rst
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Config/config.h.cmake
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/Driver/Driver.cpp

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=321621&r1=321620&r2=321621&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Mon Jan  1 05:27:01 2018
@@ -694,6 +694,79 @@ a special character, which is the conven
 option tells Clang to put double-quotes around the entire filename, which
 is the convention used by NMake and Jom.
 
+Configuration files
+---
+
+Configuration files group command-line options and allow all of them to be
+specified just by referencing the configuration file. They may be used, for
+example, to collect options required to tune compilation for particular
+target, such as -L, -I, -l, --sysroot, codegen options, etc.
+
+The command line option `--config` can be used to specify configuration
+file in a Clang invocation. For example:
+
+::
+
+clang --config /home/user/cfgs/testing.txt
+clang --config debug.cfg
+
+If the provided argument contains a directory separator, it is considered as
+a file path, and options are read from that file. Otherwise the argument is
+treated as a file name and is searched for sequentially in the directories:
+
+- user directory,
+- system directory,
+- the directory where Clang executable resides.
+
+Both user and system directories for configuration files are specified during
+clang build using CMake parameters, CLANG_CONFIG_FILE_USER_DIR and
+CLANG_CONFIG_FILE_SYSTEM_DIR respectively. The first file found is used. It is
+an error if the required file cannot be found.
+
+Another way to specify a configuration file is to encode it in executable name.
+For example, if the Clang executable is named `armv7l-clang` (it may be a
+symbolic link to `clang`), then Clang will search for file `armv7l.cfg` in the
+directory where Clang resides.
+
+If a driver mode is specified in invocation, Clang tries to find a file 
specific
+for the specified mode. For example, if the executable file is named
+`x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not 
found,
+looks for `x86_64.cfg'.
+
+If the command line contains options that effectively change target 
architecture
+(these are -m32, -EL, and some others) and the configuration file starts with 
an
+architecture name, Clang tries to load the configuration file for the effective
+architecture. For example, invocation:
+
+::
+
+x86_64-clang -m32 abc.c
+
+causes Clang search for a file `i368.cfg` first, and if no such file is found,
+Clang looks for the file `x86_64.cf

r321623 - Fixed markup formatting

2018-01-01 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Mon Jan  1 07:53:16 2018
New Revision: 321623

URL: http://llvm.org/viewvc/llvm-project?rev=321623&view=rev
Log:
Fixed markup formatting

Modified:
cfe/trunk/docs/UsersManual.rst

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=321623&r1=321622&r2=321623&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Mon Jan  1 07:53:16 2018
@@ -731,7 +731,7 @@ directory where Clang resides.
 If a driver mode is specified in invocation, Clang tries to find a file 
specific
 for the specified mode. For example, if the executable file is named
 `x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not 
found,
-looks for `x86_64.cfg'.
+looks for `x86_64.cfg`.
 
 If the command line contains options that effectively change target 
architecture
 (these are -m32, -EL, and some others) and the configuration file starts with 
an


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


r326419 - Function definition may have uninstantiated body

2018-02-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Feb 28 23:04:11 2018
New Revision: 326419

URL: http://llvm.org/viewvc/llvm-project?rev=326419&view=rev
Log:
Function definition may have uninstantiated body

Current implementation of `FunctionDecl::isDefined` does not take into
account redeclarations that do not have bodies, but the bodies can be
instantiated from corresponding templated definition. This behavior does
not allow to detect function redefinition in the cases where friend
functions is defined in class templates. For instance, the code:
```
template struct X { friend void f() {} };
X xi;
void f() {}
```
compiles successfully but must fail due to redefinition of `f`. The
declaration of the friend `f` is created when the containing template
`X` is instantiated, but it does not have a body as per 14.5.4p4
because `f` is not odr-used.

With this change the function `Sema::CheckForFunctionRedefinition`
considers functions with uninstantiated bodies as definitions.

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

Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/friend2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=326419&r1=326418&r2=326419&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Feb 28 23:04:11 2018
@@ -1925,11 +1925,25 @@ public:
 
   SourceRange getSourceRange() const override LLVM_READONLY;
 
-  /// \brief Returns true if the function has a body (definition). The
-  /// function body might be in any of the (re-)declarations of this
-  /// function. The variant that accepts a FunctionDecl pointer will
-  /// set that function declaration to the actual declaration
-  /// containing the body (if there is one).
+  // Function definitions.
+  //
+  // A function declaration may be:
+  // - a non defining declaration,
+  // - a definition. A function may be defined because:
+  //   - it has a body, or will have it in the case of late parsing.
+  //   - it has an uninstantiated body. The body does not exist because the
+  // function is not used yet, but the declaration is considered a
+  // definition and does not allow other definition of this function.
+  //   - it does not have a user specified body, but it does not allow
+  // redefinition, because it is deleted/defaulted or is defined through
+  // some other mechanism (alias, ifunc).
+
+  /// Returns true if the function has a body.
+  ///
+  /// The function body might be in any of the (re-)declarations of this
+  /// function. The variant that accepts a FunctionDecl pointer will set that
+  /// function declaration to the actual declaration containing the body (if
+  /// there is one).
   bool hasBody(const FunctionDecl *&Definition) const;
 
   bool hasBody() const override {
@@ -1941,9 +1955,11 @@ public:
   /// specific codegen.
   bool hasTrivialBody() const;
 
-  /// Returns true if the function is defined at all, including a deleted
-  /// definition. Except for the behavior when the function is deleted, behaves
-  /// like hasBody.
+  /// Returns true if the function has a definition that does not need to be
+  /// instantiated.
+  ///
+  /// The variant that accepts a FunctionDecl pointer will set that function
+  /// declaration to the declaration that is a definition (if there is one).
   bool isDefined(const FunctionDecl *&Definition) const;
 
   virtual bool isDefined() const {
@@ -1985,8 +2001,7 @@ public:
IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
   }
 
-  /// Returns whether this specific declaration of the function has a body -
-  /// that is, if it is a non-deleted definition.
+  /// Returns whether this specific declaration of the function has a body.
   bool doesThisDeclarationHaveABody() const {
 return Body || IsLateTemplateParsed;
   }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=326419&r1=326418&r2=326419&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 28 23:04:11 2018
@@ -12283,9 +12283,36 @@ Sema::CheckForFunctionRedefinition(Funct
const FunctionDecl *EffectiveDefinition,
SkipBodyInfo *SkipBody) {
   const FunctionDecl *Definition = EffectiveDefinition;
+  if (!Definition && !FD->isDefined(Definition) && !FD->isCXXClassMember()) {
+// If this is a friend function defined in a class template, it does not
+// have a body until it is used, nevertheless it is a definition, see
+// [temp.inst]p2:
+//
+// ... for the purpose of determining whethe

Re: [PATCH] D43805: Optionally use nameless IR types

2018-03-06 Thread Serge Pavlov via cfe-commits
Any feedback?

Thanks,
--Serge

2018-02-28 0:02 GMT+07:00 Serge Pavlov via Phabricator <
revi...@reviews.llvm.org>:

> sepavloff marked an inline comment as done.
> sepavloff added inline comments.
>
>
> 
> Comment at: include/clang/Driver/Options.td:1735
> +  HelpText<"Whether to use IR type names (option: none, use)">,
> +  Values<"none,use">;
>  def relocatable_pch : Flag<["-", "--"], "relocatable-pch">,
> Flags<[CC1Option]>,
> 
> rjmccall wrote:
> > This is an unusual spelling for the option in a number of ways:
> >   - We generally don't use `--` options; I think all the ones we have
> are strictly for legacy support.
> >   - A lot of similar options are in the `-f` or `-m` namespaces,
> although that's not as consistent and we could reasonably make this an
> exception.
> >   - `-foo=bar` options are generally used for options that are expected
> to take a variety of different values; this seems basically boolean.  Are
> you expecting future growth here?
> The option is in fact a three-state one, the third 'value' is absence of
> the option. In this case the option value is calculated from the type of
> action (produce ll file or not) and from the type of build (in debug builds
> types are named by default). To avoid misunderstanding I added new value,
> 'auto' for this purpose.
>
> The option was renamed to `-fir-type-names=` and it is not hidden anymore.
>
>
> Repository:
>   rC Clang
>
> https://reviews.llvm.org/D43805
>
>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r327863 - [Driver] Avoid invalidated iterator in insertTargetAndModeArgs

2018-03-19 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Mon Mar 19 09:13:43 2018
New Revision: 327863

URL: http://llvm.org/viewvc/llvm-project?rev=327863&view=rev
Log:
[Driver] Avoid invalidated iterator in insertTargetAndModeArgs

Doing an .insert() can potentially invalidate iterators by reallocating the
vector's storage. When all the stars align just right, this causes segfaults
or glibc aborts.

Gentoo Linux bug (crashes while building Chromium): 
https://bugs.gentoo.org/650082.

Patch by Hector Martin!

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

Modified:
cfe/trunk/tools/driver/driver.cpp

Modified: cfe/trunk/tools/driver/driver.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/driver.cpp?rev=327863&r1=327862&r2=327863&view=diff
==
--- cfe/trunk/tools/driver/driver.cpp (original)
+++ cfe/trunk/tools/driver/driver.cpp Mon Mar 19 09:13:43 2018
@@ -212,20 +212,21 @@ static void insertTargetAndModeArgs(cons
   // Put target and mode arguments at the start of argument list so that
   // arguments specified in command line could override them. Avoid putting
   // them at index 0, as an option like '-cc1' must remain the first.
-  auto InsertionPoint = ArgVector.begin();
-  if (InsertionPoint != ArgVector.end())
+  int InsertionPoint = 0;
+  if (ArgVector.size() > 0)
 ++InsertionPoint;
 
   if (NameParts.DriverMode) {
 // Add the mode flag to the arguments.
-ArgVector.insert(InsertionPoint,
+ArgVector.insert(ArgVector.begin() + InsertionPoint,
  GetStableCStr(SavedStrings, NameParts.DriverMode));
   }
 
   if (NameParts.TargetIsValid) {
 const char *arr[] = {"-target", GetStableCStr(SavedStrings,
   NameParts.TargetPrefix)};
-ArgVector.insert(InsertionPoint, std::begin(arr), std::end(arr));
+ArgVector.insert(ArgVector.begin() + InsertionPoint,
+ std::begin(arr), std::end(arr));
   }
 }
 


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


r348473 - Diagnose friend function template redefinitions.

2018-12-06 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Dec  6 01:35:04 2018
New Revision: 348473

URL: http://llvm.org/viewvc/llvm-project?rev=348473&view=rev
Log:
Diagnose friend function template redefinitions.

Friend function template defined in a class template becomes available if
the enclosing class template is instantiated. Until the function template
is used, it does not have a body, but still is considered a definition for
the purpose of redeclaration checks.

This change modifies redefinition check so that it can find the friend
function template definitions in instantiated classes.

Differential Revision: http://reviews.llvm.org/D21508

Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/Modules/friend-definition.cpp
cfe/trunk/test/SemaCXX/friend-template-redecl.cpp
cfe/trunk/test/SemaCXX/friend2.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=348473&r1=348472&r2=348473&view=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Thu Dec  6 01:35:04 2018
@@ -1065,11 +1065,11 @@ public:
 unsigned OldNS = IdentifierNamespace;
 assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
  IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
+ IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
"namespace includes neither ordinary nor tag");
 assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
IDNS_TagFriend | IDNS_OrdinaryFriend |
-   IDNS_LocalExtern)) &&
+   IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
"namespace includes other than ordinary or tag");
 
 Decl *Prev = getPreviousDecl();
@@ -1082,7 +1082,8 @@ public:
 IdentifierNamespace |= IDNS_Tag | IDNS_Type;
 }
 
-if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
+if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend |
+ IDNS_LocalExtern | IDNS_NonMemberOperator)) {
   IdentifierNamespace |= IDNS_OrdinaryFriend;
   if (PerformFriendInjection ||
   (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=348473&r1=348472&r2=348473&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec  6 01:35:04 2018
@@ -12737,6 +12737,29 @@ Sema::CheckForFunctionRedefinition(Funct
   }
 }
   }
+
+  if (!Definition)
+// Similar to friend functions a friend function template may be a
+// definition and do not have a body if it is instantiated in a class
+// template.
+if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) {
+  for (auto I : FTD->redecls()) {
+auto D = cast(I);
+if (D != FTD) {
+  assert(!D->isThisDeclarationADefinition() &&
+ "More than one definition in redeclaration chain");
+  if (D->getFriendObjectKind() != Decl::FOK_None)
+if (FunctionTemplateDecl *FT =
+   D->getInstantiatedFromMemberTemplate()) 
{
+  if (FT->isThisDeclarationADefinition()) {
+Definition = D->getTemplatedDecl();
+break;
+  }
+}
+}
+  }
+}
+
   if (!Definition)
 return;
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=348473&r1=348472&r2=348473&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Dec  6 01:35:04 2018
@@ -1817,7 +1817,9 @@ Decl *TemplateDeclInstantiator::VisitFun
   // If the original function was part of a friend declaration,
   // inherit its namespace state and add it to the owner.
   if (isFriend) {
-PrincipalDecl->setObjectOfFriendDecl();
+Function->setObjectOfFriendDecl();
+if (FunctionTemplateDecl *FT = Function->getDescribedFunctionTemplate())
+  FT->setObjectOfFriendDecl();
 DC->makeDeclVisibleInContext(PrincipalDecl);
 
 bool QueuedInstantiation = false;

Modified: cfe/trunk/test/Modules/friend-definition.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/friend-definition.cpp?rev=348473&r1=348472&r2=348473&view=diff
==
--- cfe/trunk/test/Modules/friend-definition.cpp (orig

r311981 - Use class to pass information about executable name

2017-08-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Mon Aug 28 22:22:26 2017
New Revision: 311981

URL: http://llvm.org/viewvc/llvm-project?rev=311981&view=rev
Log:
Use class to pass information about executable name

Information about clang executable name components, such as target and
driver mode, was passes in std::pair. With this change it is passed in
a special structure. It improves readability and makes access to this
information more convenient.

NFC.

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

Modified:
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/include/clang/Driver/ToolChain.h
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/lib/Driver/ToolChain.cpp
cfe/trunk/lib/Tooling/Tooling.cpp
cfe/trunk/tools/driver/driver.cpp
cfe/trunk/unittests/Driver/CMakeLists.txt
cfe/trunk/unittests/Driver/ToolChainTest.cpp

Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=311981&r1=311980&r2=311981&view=diff
==
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Mon Aug 28 22:22:26 2017
@@ -129,6 +129,9 @@ public:
   /// The original path to the clang executable.
   std::string ClangExecutable;
 
+  /// Target and driver mode components extracted from clang executable name.
+  ParsedClangName ClangNameParts;
+
   /// The path to the installed clang directory, if any.
   std::string InstalledDir;
 
@@ -284,6 +287,8 @@ public:
 
   void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
 
+  void setTargetAndMode(const ParsedClangName &TM) { ClangNameParts = TM; }
+
   const std::string &getTitle() { return DriverTitle; }
   void setTitle(std::string Value) { DriverTitle = std::move(Value); }
 

Modified: cfe/trunk/include/clang/Driver/ToolChain.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=311981&r1=311980&r2=311981&view=diff
==
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)
+++ cfe/trunk/include/clang/Driver/ToolChain.h Mon Aug 28 22:22:26 2017
@@ -46,6 +46,28 @@ namespace driver {
   class Tool;
   class XRayArgs;
 
+/// Helper structure used to pass information extracted from clang executable
+/// name such as `i686-linux-android-g++`.
+///
+struct ParsedClangName {
+  /// Target part of the executable name, as `i686-linux-android`.
+  std::string TargetPrefix;
+  /// Driver mode part of the executable name, as `g++`.
+  std::string ModeSuffix;
+  /// Corresponding driver mode argument, as '--driver-mode=g++'
+  const char *DriverMode;
+  /// True if TargetPrefix is recognized as a registered target name.
+  bool TargetIsValid;
+
+  ParsedClangName() : DriverMode(nullptr), TargetIsValid(false) {}
+  ParsedClangName(std::string Suffix, const char *Mode)
+  : ModeSuffix(Suffix), DriverMode(Mode), TargetIsValid(false) {}
+  ParsedClangName(std::string Target, std::string Suffix, const char *Mode,
+  bool IsRegistered)
+  : TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode),
+TargetIsValid(IsRegistered) {}
+};
+
 /// ToolChain - Access to tools for a single platform.
 class ToolChain {
 public:
@@ -193,13 +215,16 @@ public:
   /// For example, when called with i686-linux-android-g++, the first element
   /// of the return value will be set to `"i686-linux-android"` and the second
   /// will be set to "--driver-mode=g++"`.
+  /// It is OK if the target name is not registered. In this case the return
+  /// value contains false in the field TargetIsValid.
   ///
   /// \pre `llvm::InitializeAllTargets()` has been called.
   /// \param ProgName The name the Clang driver was invoked with (from,
-  /// e.g., argv[0])
-  /// \return A pair of (`target`, `mode-flag`), where one or both may be 
empty.
-  static std::pair
-  getTargetAndModeFromProgramName(StringRef ProgName);
+  /// e.g., argv[0]).
+  /// \return A structure of type ParsedClangName that contains the executable
+  /// name parts.
+  ///
+  static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName);
 
   // Tool access.
 

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=311981&r1=311980&r2=311981&view=diff
==
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Mon Aug 28 22:22:26 2017
@@ -119,9 +119,8 @@ Driver::Driver(StringRef ClangExecutable
 
 void Driver::ParseDriverMode(StringRef ProgramName,
  ArrayRef Args) {
-  auto Default = ToolChain::getTargetAndModeFromProgramName(ProgramName);
-  StringRef DefaultMode(Default.second);
-  setDriverModeFromOption(DefaultMode);
+  ClangNameParts = ToolChain::getTargetAndModeFromProgramName(Progra

r313760 - Put target deduced from executable name at the start of argument list

2017-09-20 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Sep 20 08:22:27 2017
New Revision: 313760

URL: http://llvm.org/viewvc/llvm-project?rev=313760&view=rev
Log:
Put target deduced from executable name at the start of argument list

When clang is called as 'target-clang', put deduced target option at
the start of argument list so that option '--target=' specified in command
line could override it.

This change fixes PR34671.

Added:
cfe/trunk/test/Driver/target-override.c
Modified:
cfe/trunk/tools/driver/driver.cpp

Added: cfe/trunk/test/Driver/target-override.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/target-override.c?rev=313760&view=auto
==
--- cfe/trunk/test/Driver/target-override.c (added)
+++ cfe/trunk/test/Driver/target-override.c Wed Sep 20 08:22:27 2017
@@ -0,0 +1,16 @@
+// REQUIRES: shell
+// REQUIRES: x86-registered-target
+
+// RUN: mkdir -p %T/testbin
+// RUN: [ ! -s %T/testbin/i386-clang ] || rm %T/testbin/i386-clang
+// RUN: ln -s %clang %T/testbin/i386-clang
+
+// Check if invocation of "foo-clang" adds option "-target foo".
+//
+// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes %s -### 2>&1 | 
FileCheck -check-prefix CHECK-TG1 %s
+// CHECK-TG1: Target: i386
+
+// Check if invocation of "foo-clang -target bar" overrides option "-target 
foo".
+//
+// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes -target x86_64 %s -### 
2>&1 | FileCheck -check-prefix CHECK-TG2 %s
+// CHECK-TG2: Target: x86_64

Modified: cfe/trunk/tools/driver/driver.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/driver.cpp?rev=313760&r1=313759&r2=313760&view=diff
==
--- cfe/trunk/tools/driver/driver.cpp (original)
+++ cfe/trunk/tools/driver/driver.cpp Wed Sep 20 08:22:27 2017
@@ -209,16 +209,23 @@ extern int cc1as_main(ArrayRef &ArgVector,
 std::set &SavedStrings) {
+  // Put target and mode arguments at the start of argument list so that
+  // arguments specified in command line could override them. Avoid putting
+  // them at index 0, as an option like '-cc1' must remain the first.
+  auto InsertionPoint = ArgVector.begin();
+  if (InsertionPoint != ArgVector.end())
+++InsertionPoint;
+
   if (NameParts.DriverMode) {
 // Add the mode flag to the arguments.
-ArgVector.insert(ArgVector.end(),
+ArgVector.insert(InsertionPoint,
  GetStableCStr(SavedStrings, NameParts.DriverMode));
   }
 
   if (NameParts.TargetIsValid) {
 const char *arr[] = {"-target", GetStableCStr(SavedStrings,
   NameParts.TargetPrefix)};
-ArgVector.insert(ArgVector.end(), std::begin(arr), std::end(arr));
+ArgVector.insert(InsertionPoint, std::begin(arr), std::end(arr));
   }
 }
 


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


r367545 - [Parser] Change parameter type from int to enum

2019-08-01 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Aug  1 04:46:28 2019
New Revision: 367545

URL: http://llvm.org/viewvc/llvm-project?rev=367545&view=rev
Log:
[Parser] Change parameter type from int to enum

Some parser functions accept argument of type unsigned while it is
actually of type DeclSpec::TST. No functional changes.

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

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=367545&r1=367544&r2=367545&view=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Aug  1 04:46:28 2019
@@ -972,7 +972,7 @@ private:
   };
 
   /// Consume any extra semi-colons until the end of the line.
-  void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
+  void ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST T = TST_unspecified);
 
   /// Return false if the next token is an identifier. An 'expected identifier'
   /// error is emitted otherwise.
@@ -2160,7 +2160,7 @@ private:
   const ParsedTemplateInfo &TemplateInfo,
   AccessSpecifier AS, DeclSpecContext DSC);
   void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
-  void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+  void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
 Decl *TagDecl);
 
   void ParseStructDeclaration(

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=367545&r1=367544&r2=367545&view=diff
==
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Aug  1 04:46:28 2019
@@ -4098,7 +4098,7 @@ void Parser::ParseStructDeclaration(
 /// [OBC]   '@' 'defs' '(' class-name ')'
 ///
 void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
-  unsigned TagType, Decl *TagDecl) {
+  DeclSpec::TST TagType, Decl *TagDecl) {
   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
   "parsing struct/union body");
   assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=367545&r1=367544&r2=367545&view=diff
==
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Aug  1 04:46:28 2019
@@ -4337,7 +4337,7 @@ void Parser::ParseMicrosoftIfExistsClass
   while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
 // __if_exists, __if_not_exists can nest.
 if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
-  ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType,
+  ParseMicrosoftIfExistsClassDeclaration(TagType,
  AccessAttrs, CurAS);
   continue;
 }

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=367545&r1=367544&r2=367545&view=diff
==
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Aug  1 04:46:28 2019
@@ -174,7 +174,7 @@ bool Parser::ExpectAndConsumeSemi(unsign
   return ExpectAndConsume(tok::semi, DiagID);
 }
 
-void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST) {
+void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {
   if (!Tok.is(tok::semi)) return;
 
   bool HadMultipleSemis = false;
@@ -202,7 +202,7 @@ void Parser::ConsumeExtraSemi(ExtraSemiK
 
   if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
 Diag(StartLoc, diag::ext_extra_semi)
-<< Kind << DeclSpec::getSpecifierName((DeclSpec::TST)TST,
+<< Kind << DeclSpec::getSpecifierName(TST,
 
Actions.getASTContext().getPrintingPolicy())
 << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
   else


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


r367575 - [Parser] Use special definition for pragma annotations

2019-08-01 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Aug  1 08:15:10 2019
New Revision: 367575

URL: http://llvm.org/viewvc/llvm-project?rev=367575&view=rev
Log:
[Parser] Use special definition for pragma annotations

Previously pragma annotation tokens were described as any other
annotations in TokenKinds.def. This change introduces special macro
PRAGMA_ANNOTATION for the pragma descriptions. It allows implementing
checks that deal with pragma annotations only.

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

Modified:
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Basic/TokenKinds.h
cfe/trunk/lib/Basic/TokenKinds.cpp

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=367575&r1=367574&r2=367575&view=diff
==
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Aug  1 08:15:10 2019
@@ -68,6 +68,9 @@
 #ifndef ANNOTATION
 #define ANNOTATION(X) TOK(annot_ ## X)
 #endif
+#ifndef PRAGMA_ANNOTATION
+#define PRAGMA_ANNOTATION(X) ANNOTATION(X)
+#endif
 
 
//===--===//
 // Preprocessor keywords.
@@ -729,103 +732,103 @@ ANNOTATION(decltype) // annotation f
 // Annotation for #pragma unused(...)
 // For each argument inside the parentheses the pragma handler will produce
 // one 'pragma_unused' annotation token followed by the argument token.
-ANNOTATION(pragma_unused)
+PRAGMA_ANNOTATION(pragma_unused)
 
 // Annotation for #pragma GCC visibility...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_vis)
+PRAGMA_ANNOTATION(pragma_vis)
 
 // Annotation for #pragma pack...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_pack)
+PRAGMA_ANNOTATION(pragma_pack)
 
 // Annotation for #pragma clang __debug parser_crash...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_parser_crash)
+PRAGMA_ANNOTATION(pragma_parser_crash)
 
 // Annotation for #pragma clang __debug captured...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_captured)
+PRAGMA_ANNOTATION(pragma_captured)
 
 // Annotation for #pragma clang __debug dump...
 // The lexer produces these so that the parser and semantic analysis can
 // look up and dump the operand.
-ANNOTATION(pragma_dump)
+PRAGMA_ANNOTATION(pragma_dump)
 
 // Annotation for #pragma ms_struct...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_msstruct)
+PRAGMA_ANNOTATION(pragma_msstruct)
 
 // Annotation for #pragma align...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_align)
+PRAGMA_ANNOTATION(pragma_align)
 
 // Annotation for #pragma weak id
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_weak)
+PRAGMA_ANNOTATION(pragma_weak)
 
 // Annotation for #pragma weak id = id
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_weakalias)
+PRAGMA_ANNOTATION(pragma_weakalias)
 
 // Annotation for #pragma redefine_extname...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_redefine_extname)
+PRAGMA_ANNOTATION(pragma_redefine_extname)
 
 // Annotation for #pragma STDC FP_CONTRACT...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_fp_contract)
+PRAGMA_ANNOTATION(pragma_fp_contract)
 
 // Annotation for #pragma STDC FENV_ACCESS
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_fenv_access)
+PRAGMA_ANNOTATION(pragma_fenv_access)
 
 // Annotation for #pragma pointers_to_members...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_ms_pointers_to_members)
+PRAGMA_ANNOTATION(pragma_ms_pointers_to_members)
 
 // Annotation for #pragma vtordisp...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_ms_vtordisp)
+PRAGMA_ANNOTATION(pragma_ms_vtordisp)
 
 // Annotation for all microsoft #pragmas...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_ms_pragma)
+PRAGMA_ANNOTATION(pragma_ms_pragma)
 
 // Annotation for #pragma OPENCL EXTENSION...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
-ANNOTATION(pragma_opencl_extension)
+PRAGMA_ANNOTATION(pragma_opencl_extension)
 
 // Annotations for OpenMP pra

r367759 - Use switch instead of series of comparisons

2019-08-03 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sat Aug  3 09:32:49 2019
New Revision: 367759

URL: http://llvm.org/viewvc/llvm-project?rev=367759&view=rev
Log:
Use switch instead of series of comparisons

This is style correction, no functional changes.

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

Modified:
cfe/trunk/include/clang/Basic/TokenKinds.h
cfe/trunk/lib/Basic/TokenKinds.cpp

Modified: cfe/trunk/include/clang/Basic/TokenKinds.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.h?rev=367759&r1=367758&r2=367759&view=diff
==
--- cfe/trunk/include/clang/Basic/TokenKinds.h (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.h Sat Aug  3 09:32:49 2019
@@ -90,13 +90,7 @@ inline bool isLiteral(TokenKind K) {
 }
 
 /// Return true if this is any of tok::annot_* kinds.
-inline bool isAnnotation(TokenKind K) {
-#define ANNOTATION(NAME) \
-  if (K == tok::annot_##NAME) \
-return true;
-#include "clang/Basic/TokenKinds.def"
-  return false;
-}
+bool isAnnotation(TokenKind K);
 
 /// Return true if this is an annotation token representing a pragma.
 bool isPragmaAnnotation(TokenKind K);

Modified: cfe/trunk/lib/Basic/TokenKinds.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TokenKinds.cpp?rev=367759&r1=367758&r2=367759&view=diff
==
--- cfe/trunk/lib/Basic/TokenKinds.cpp (original)
+++ cfe/trunk/lib/Basic/TokenKinds.cpp Sat Aug  3 09:32:49 2019
@@ -46,6 +46,16 @@ const char *tok::getKeywordSpelling(Toke
   return nullptr;
 }
 
+bool tok::isAnnotation(TokenKind Kind) {
+  switch (Kind) {
+#define ANNOTATION(X) case annot_ ## X: return true;
+#include "clang/Basic/TokenKinds.def"
+  default:
+break;
+  }
+  return false;
+}
+
 bool tok::isPragmaAnnotation(TokenKind Kind) {
   switch (Kind) {
 #define PRAGMA_ANNOTATION(X) case annot_ ## X: return true;


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


r367779 - [Parser] Emit descriptive diagnostic for misplaced pragma

2019-08-04 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sun Aug  4 03:08:51 2019
New Revision: 367779

URL: http://llvm.org/viewvc/llvm-project?rev=367779&view=rev
Log:
[Parser] Emit descriptive diagnostic for misplaced pragma

If a class or struct or union declaration contains a pragma that
is not valid in this context, compiler issues generic error like
"expected member name or ';' after declaration specifiers". With this
change the error tells that this pragma cannot appear in this declaration.

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

Added:
cfe/trunk/test/Parser/pragma-fp-contract.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/Parser/pragma-attribute-context.cpp
cfe/trunk/test/Parser/pragma-fp-contract.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=367779&r1=367778&r2=367779&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Aug  4 03:08:51 
2019
@@ -974,6 +974,8 @@ def warn_pragma_missing_argument : Warni
 def warn_pragma_invalid_argument : Warning<
   "unexpected argument '%0' to '#pragma %1'%select{|; expected %3}2">, 
InGroup;
 
+def err_pragma_misplaced_in_decl : Error<"this pragma cannot appear in %0 
declaration">;
+
 // '#pragma clang section' related errors
 def err_pragma_expected_clang_section_name : Error<
   "expected one of [bss|data|rodata|text] section kind in '#pragma %0'">;

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=367779&r1=367778&r2=367779&view=diff
==
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Aug  4 03:08:51 2019
@@ -4148,6 +4148,14 @@ void Parser::ParseStructUnionBody(Source
   continue;
 }
 
+if (tok::isPragmaAnnotation(Tok.getKind())) {
+  Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
+  << DeclSpec::getSpecifierName(
+ TagType, Actions.getASTContext().getPrintingPolicy());
+  ConsumeAnnotationToken();
+  continue;
+}
+
 if (!Tok.is(tok::at)) {
   auto CFieldCallback = [&](ParsingFieldDeclarator &FD) {
 // Install the declarator into the current TagDecl.

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=367779&r1=367778&r2=367779&view=diff
==
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sun Aug  4 03:08:51 2019
@@ -3134,6 +3134,13 @@ Parser::DeclGroupPtrTy Parser::ParseCXXC
   TagDecl);
 
   default:
+if (tok::isPragmaAnnotation(Tok.getKind())) {
+  Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
+  << DeclSpec::getSpecifierName(TagType,
+   
Actions.getASTContext().getPrintingPolicy());
+  ConsumeAnnotationToken();
+  return nullptr;
+}
 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
   }
 }

Modified: cfe/trunk/test/Parser/pragma-attribute-context.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-attribute-context.cpp?rev=367779&r1=367778&r2=367779&view=diff
==
--- cfe/trunk/test/Parser/pragma-attribute-context.cpp (original)
+++ cfe/trunk/test/Parser/pragma-attribute-context.cpp Sun Aug  4 03:08:51 2019
@@ -31,8 +31,7 @@ int c = my_ns::nested::h(); // expected-
 
 struct InStruct {
   // FIXME: This asserts in Objective-C++!
-  // FIXME: This is a horrible diagnostic!
 #ifndef __OBJC__
-  BEGIN_PRAGMA // expected-error {{expected member name or ';' after 
declaration specifiers}}
+  BEGIN_PRAGMA // expected-error {{this pragma cannot appear in struct 
declaration}}
 #endif
 };

Modified: cfe/trunk/test/Parser/pragma-fp-contract.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-fp-contract.c?rev=367779&r1=367778&r2=367779&view=diff
==
--- cfe/trunk/test/Parser/pragma-fp-contract.c (original)
+++ cfe/trunk/test/Parser/pragma-fp-contract.c Sun Aug  4 03:08:51 2019
@@ -10,3 +10,16 @@ void f2(void) {
   #pragma STDC FP_CONTRACT OFF
   #pragma STDC FP_CONTRACT ON 
 }
+
+struct S1 {
+// expected-error@+1 {{this pragma cannot appear in struct declaration}}
+#pragma STDC FP_CONTRACT ON
+  float f1;
+};
+
+union U1 {
+  float f1;
+  float f2;
+// expected-error@+1 {{this pr

r373147 - Driver tests: set `--sysroot=""` to support clang with `DEFAULT_SYSROOT`

2019-09-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Sat Sep 28 05:21:06 2019
New Revision: 373147

URL: http://llvm.org/viewvc/llvm-project?rev=373147&view=rev
Log:
Driver tests: set `--sysroot=""` to support clang with `DEFAULT_SYSROOT`

When testing clang that has been compiled with `-DDEFAULT_SYSROOT` set to some 
path,
some tests would fail. Override sysroot to be empty string for the tests to 
succeed
when clang is configured with `DEFAULT_SYSROOT`.

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

Patch by Sergej Jaskiewicz .

Modified:
cfe/trunk/test/Driver/darwin-sdkroot.c
cfe/trunk/test/Driver/gcc-toolchain.cpp
cfe/trunk/test/Driver/mips-mti.cpp
cfe/trunk/test/Driver/msp430-toolchain.c
cfe/trunk/unittests/Driver/ToolChainTest.cpp

Modified: cfe/trunk/test/Driver/darwin-sdkroot.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/darwin-sdkroot.c?rev=373147&r1=373146&r2=373147&view=diff
==
--- cfe/trunk/test/Driver/darwin-sdkroot.c (original)
+++ cfe/trunk/test/Driver/darwin-sdkroot.c Sat Sep 28 05:21:06 2019
@@ -2,7 +2,7 @@
 //
 // RUN: rm -rf %t.tmpdir
 // RUN: mkdir -p %t.tmpdir
-// RUN: env SDKROOT=%t.tmpdir %clang -target x86_64-apple-darwin10 \
+// RUN: env SDKROOT=%t.tmpdir %clang -target x86_64-apple-darwin10 
--sysroot="" \
 // RUN:   -c %s -### 2> %t.log
 // RUN: FileCheck --check-prefix=CHECK-BASIC < %t.log %s
 //
@@ -13,7 +13,7 @@
 // Check that we don't use SDKROOT as the default if it is not a valid path.
 //
 // RUN: rm -rf %t.nonpath
-// RUN: env SDKROOT=%t.nonpath %clang -target x86_64-apple-darwin10 \
+// RUN: env SDKROOT=%t.nonpath %clang -target x86_64-apple-darwin10 
--sysroot="" \
 // RUN:   -c %s -### 2> %t.log
 // RUN: FileCheck --check-prefix=CHECK-NONPATH < %t.log %s
 //
@@ -23,7 +23,7 @@
 
 // Check that we don't use SDKROOT as the default if it is just "/"
 //
-// RUN: env SDKROOT=/ %clang -target x86_64-apple-darwin10 \
+// RUN: env SDKROOT=/ %clang -target x86_64-apple-darwin10 --sysroot="" \
 // RUN:   -c %s -### 2> %t.log
 // RUN: FileCheck --check-prefix=CHECK-NONROOT < %t.log %s
 //
@@ -43,7 +43,7 @@
 //
 // RUN: rm -rf %t/SDKs/iPhoneOS8.0.0.sdk
 // RUN: mkdir -p %t/SDKs/iPhoneOS8.0.0.sdk
-// RUN: env SDKROOT=%t/SDKs/iPhoneOS8.0.0.sdk %clang -target 
arm64-apple-darwin %s -### 2>&1 \
+// RUN: env SDKROOT=%t/SDKs/iPhoneOS8.0.0.sdk %clang -target 
arm64-apple-darwin --sysroot="" %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-IPHONE %s
 //
 // CHECK-IPHONE: clang
@@ -55,7 +55,7 @@
 //
 // RUN: rm -rf %t/SDKs/iPhoneSimulator8.0.sdk
 // RUN: mkdir -p %t/SDKs/iPhoneSimulator8.0.sdk
-// RUN: env SDKROOT=%t/SDKs/iPhoneSimulator8.0.sdk %clang -target 
x86_64-apple-darwin %s -### 2>&1 \
+// RUN: env SDKROOT=%t/SDKs/iPhoneSimulator8.0.sdk %clang -target 
x86_64-apple-darwin --sysroot="" %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-SIMULATOR %s
 //
 // CHECK-SIMULATOR: clang
@@ -66,7 +66,7 @@
 //
 // RUN: rm -rf %t/SDKs/MacOSX10.10.0.sdk
 // RUN: mkdir -p %t/SDKs/MacOSX10.10.0.sdk
-// RUN: env SDKROOT=%t/SDKs/MacOSX10.10.0.sdk %clang -target 
x86_64-apple-darwin %s -### 2>&1 \
+// RUN: env SDKROOT=%t/SDKs/MacOSX10.10.0.sdk %clang -target 
x86_64-apple-darwin --sysroot="" %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-MACOSX %s
 //
 // CHECK-MACOSX: clang

Modified: cfe/trunk/test/Driver/gcc-toolchain.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/gcc-toolchain.cpp?rev=373147&r1=373146&r2=373147&view=diff
==
--- cfe/trunk/test/Driver/gcc-toolchain.cpp (original)
+++ cfe/trunk/test/Driver/gcc-toolchain.cpp Sat Sep 28 05:21:06 2019
@@ -3,12 +3,14 @@
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t 2>&1 \
 // RUN: --target=i386-unknown-linux -stdlib=libstdc++ \
 // RUN: --gcc-toolchain=%S/Inputs/ubuntu_11.04_multiarch_tree/usr \
+// RUN: --sysroot="" \
 // RUN:   | FileCheck %s
 //
 // Additionally check that the legacy spelling of the flag works.
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t 2>&1 \
 // RUN: --target=i386-unknown-linux -stdlib=libstdc++ \
 // RUN: -gcc-toolchain %S/Inputs/ubuntu_11.04_multiarch_tree/usr \
+// RUN: --sysroot="" \
 // RUN:   | FileCheck %s
 //
 // Test for header search toolchain detection.

Modified: cfe/trunk/test/Driver/mips-mti.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/mips-mti.cpp?rev=373147&r1=373146&r2=373147&view=diff
==
--- cfe/trunk/test/Driver/mips-mti.cpp (original)
+++ cfe/trunk/test/Driver/mips-mti.cpp Sat Sep 28 05:21:06 2019
@@ -4,6 +4,7 @@
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:--target=mips-mti-linux-gnu \
 // RUN:--gcc-toolchain=%S/Inputs/mips_mti_tree \
+// RUN:--sysroot="" \
 // RUN:-stdlib=libstdc++ \
 // RUN

r373565 - Fix driver tests when `LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` is `ON`

2019-10-02 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Oct  2 21:52:46 2019
New Revision: 373565

URL: http://llvm.org/viewvc/llvm-project?rev=373565&view=rev
Log:
Fix driver tests when `LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` is `ON`

Some Driver tests relied on the default resource direcory having per-os per-arch
subdirectory layout, and when clang is built with 
`-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON`,
those test fail, because clang by default assumes per-target subdirectories.

Explicitly set `-resource-dir` flag to point to a tree with per-os per-arch 
layout.

See also: D45604, D62469

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

Patch by Sergej Jaskiewicz .

Modified:
cfe/trunk/test/Driver/arm-compiler-rt.c
cfe/trunk/test/Driver/print-libgcc-file-name-clangrt.c

Modified: cfe/trunk/test/Driver/arm-compiler-rt.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/arm-compiler-rt.c?rev=373565&r1=373564&r2=373565&view=diff
==
--- cfe/trunk/test/Driver/arm-compiler-rt.c (original)
+++ cfe/trunk/test/Driver/arm-compiler-rt.c Wed Oct  2 21:52:46 2019
@@ -1,21 +1,42 @@
-// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -### %s 2>&1 | 
FileCheck %s -check-prefix ARM-GNUEABI
+// RUN: %clang -target arm-linux-gnueabi \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-GNUEABI
 // ARM-GNUEABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a"
 
-// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -mfloat-abi=hard 
-### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABI-ABI
+// RUN: %clang -target arm-linux-gnueabi \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-GNUEABI-ABI
 // ARM-GNUEABI-ABI: "{{.*[/\\]}}libclang_rt.builtins-armhf.a"
 
-// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -### %s 2>&1 | 
FileCheck %s -check-prefix ARM-GNUEABIHF
+// RUN: %clang -target arm-linux-gnueabihf \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-GNUEABIHF
 // ARM-GNUEABIHF: "{{.*[/\\]}}libclang_rt.builtins-armhf.a"
 
-// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -mfloat-abi=soft 
-### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABIHF-ABI
+// RUN: %clang -target arm-linux-gnueabihf \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -mfloat-abi=soft -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-GNUEABIHF-ABI
 // ARM-GNUEABIHF-ABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a"
 
-// RUN: %clang -target arm-windows-itanium -rtlib=compiler-rt -### %s 2>&1 | 
FileCheck %s -check-prefix ARM-WINDOWS
+// RUN: %clang -target arm-windows-itanium \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-WINDOWS
 // ARM-WINDOWS: "{{.*[/\\]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt -### %s 2>&1 | 
FileCheck %s -check-prefix ARM-ANDROID
+// RUN: %clang -target arm-linux-androideabi \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-ANDROID
 // ARM-ANDROID: "{{.*[/\\]}}libclang_rt.builtins-arm-android.a"
 
-// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt 
-mfloat-abi=hard -### %s 2>&1 | FileCheck %s -check-prefix ARM-ANDROIDHF
+// RUN: %clang -target arm-linux-androideabi \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN: -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix ARM-ANDROIDHF
 // ARM-ANDROIDHF: "{{.*[/\\]}}libclang_rt.builtins-armhf-android.a"
 

Modified: cfe/trunk/test/Driver/print-libgcc-file-name-clangrt.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/print-libgcc-file-name-clangrt.c?rev=373565&r1=373564&r2=373565&view=diff
==
--- cfe/trunk/test/Driver/print-libgcc-file-name-clangrt.c (original)
+++ cfe/trunk/test/Driver/print-libgcc-file-name-clangrt.c Wed Oct  2 21:52:46 
2019
@@ -2,11 +2,13 @@
 
 // RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
 // RUN: --target=x86_64-pc-linux \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
 // RUN:   | FileCheck --check-prefix=CHECK-CLANGRT-X8664 %s
 // CHECK-CLANGRT-X8664: libclang_rt.builtins-x86_64.a
 
 // RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
 // RUN: --target=i386-pc-linux \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
 // RUN: 

r330926 - [ConfigFiles] Update argument strings when merging argrument lists

2018-04-25 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Apr 25 23:28:47 2018
New Revision: 330926

URL: http://llvm.org/viewvc/llvm-project?rev=330926&view=rev
Log:
[ConfigFiles] Update argument strings when merging argrument lists

Implementation of `InputArgList` assumes its field `ArgStrings` contains
strings for each argument exactly in the same order. This condition was
broken when arguments from config file and from invocation were merged.

This change fixes https://bugs.llvm.org/show_bug.cgi?id=37196 (Clang
config files can crash argument handling).

Added:
cfe/trunk/test/Driver/Inputs/empty.cfg
cfe/trunk/test/Driver/config-file4.c
Modified:
cfe/trunk/lib/Driver/Driver.cpp

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=330926&r1=330925&r2=330926&view=diff
==
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Wed Apr 25 23:28:47 2018
@@ -876,11 +876,14 @@ Compilation *Driver::BuildCompilation(Ar
   : std::move(*CLOptions));
   if (HasConfigFile)
 for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  unsigned Index = Args.MakeIndex(Opt->getSpelling());
   const Arg *BaseArg = &Opt->getBaseArg();
   if (BaseArg == Opt)
 BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
- Args.size(), BaseArg);
+ Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();

Added: cfe/trunk/test/Driver/Inputs/empty.cfg
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/empty.cfg?rev=330926&view=auto
==
(empty)

Added: cfe/trunk/test/Driver/config-file4.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/config-file4.c?rev=330926&view=auto
==
--- cfe/trunk/test/Driver/config-file4.c (added)
+++ cfe/trunk/test/Driver/config-file4.c Wed Apr 25 23:28:47 2018
@@ -0,0 +1,2 @@
+// RUN: %clang --config %S/Inputs/empty.cfg -Wall -Wextra -Wformat 
-Wstrict-aliasing -Wshadow -Wpacked -Winline -Wimplicit-function-declaration -c 
%s -O2 -o /dev/null -v 2>&1 | FileCheck %s -check-prefix PR37196
+// PR37196: Configuration file: {{.*}}/empty.cfg


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


r330927 - Make test more platform neutral

2018-04-26 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Thu Apr 26 01:08:25 2018
New Revision: 330927

URL: http://llvm.org/viewvc/llvm-project?rev=330927&view=rev
Log:
Make test more platform neutral

Modified:
cfe/trunk/test/Driver/config-file4.c

Modified: cfe/trunk/test/Driver/config-file4.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/config-file4.c?rev=330927&r1=330926&r2=330927&view=diff
==
--- cfe/trunk/test/Driver/config-file4.c (original)
+++ cfe/trunk/test/Driver/config-file4.c Thu Apr 26 01:08:25 2018
@@ -1,2 +1,2 @@
 // RUN: %clang --config %S/Inputs/empty.cfg -Wall -Wextra -Wformat 
-Wstrict-aliasing -Wshadow -Wpacked -Winline -Wimplicit-function-declaration -c 
%s -O2 -o /dev/null -v 2>&1 | FileCheck %s -check-prefix PR37196
-// PR37196: Configuration file: {{.*}}/empty.cfg
+// PR37196: Configuration file: {{.*}}empty.cfg


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


[libcxxabi] r336312 - [demangler] Avoid alignment warning

2018-07-04 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Jul  4 23:24:29 2018
New Revision: 336312

URL: http://llvm.org/viewvc/llvm-project?rev=336312&view=rev
Log:
[demangler] Avoid alignment warning

The alignment specified by a constant for the field
`BumpPointerAllocator::InitialBuffer` exceeded the alignment
guaranteed by `malloc` and `new` on Windows. This change set
the alignment value to that of `long double`, which is defined
by the used platform.

It fixes https://bugs.llvm.org/show_bug.cgi?id=37944.

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

Modified:
libcxxabi/trunk/src/cxa_demangle.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=336312&r1=336311&r2=336312&view=diff
==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Wed Jul  4 23:24:29 2018
@@ -1890,7 +1890,7 @@ class BumpPointerAllocator {
   static constexpr size_t AllocSize = 4096;
   static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
 
-  alignas(16) char InitialBuffer[AllocSize];
+  alignas(long double) char InitialBuffer[AllocSize];
   BlockMeta* BlockList = nullptr;
 
   void grow() {


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


[clang] 61f72dd - [FPEnv] Small fixes to implementation of flt.rounds

2020-05-25 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-05-26T13:19:01+07:00
New Revision: 61f72dd8ace7c4bea1ae74d9734d2b02946b4898

URL: 
https://github.com/llvm/llvm-project/commit/61f72dd8ace7c4bea1ae74d9734d2b02946b4898
DIFF: 
https://github.com/llvm/llvm-project/commit/61f72dd8ace7c4bea1ae74d9734d2b02946b4898.diff

LOG: [FPEnv] Small fixes to implementation of flt.rounds

This change makes minor correction to the implementation of intrinsic
`llvm.flt.rounds`:
- Added documentation entry in LangRef,
- Attributes of the intrinsic changed to be in line with other functions
  dependent of floating-point environment.

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

Added: 


Modified: 
clang/include/clang/Basic/Builtins.def
llvm/docs/LangRef.rst
llvm/include/llvm/IR/Intrinsics.td

Removed: 




diff  --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 4f1a7f24c432..4c43d63ffec4 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -323,6 +323,9 @@ BUILTIN(__builtin_truncf, "ff", "Fnc")
 BUILTIN(__builtin_truncl, "LdLd", "Fnc")
 BUILTIN(__builtin_truncf16, "hh", "Fnc")
 
+// Access to floating point environment
+BUILTIN(__builtin_flt_rounds, "i", "n")
+
 // C99 complex builtins
 BUILTIN(__builtin_cabs, "dXd", "Fne")
 BUILTIN(__builtin_cabsf, "fXf", "Fne")
@@ -517,7 +520,6 @@ BUILTIN(__builtin_return_address, "v*IUi", "n")
 BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
 BUILTIN(__builtin_frame_address, "v*IUi", "n")
 BUILTIN(__builtin___clear_cache, "vc*c*", "n")
-BUILTIN(__builtin_flt_rounds, "i", "nc")
 BUILTIN(__builtin_setjmp, "iv**", "j")
 BUILTIN(__builtin_longjmp, "vv**i", "r")
 BUILTIN(__builtin_unwind_init, "v", "")

diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index bf0627e44196..8bcad09964e2 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -18284,6 +18284,46 @@ This function returns the same values as the libm 
``trunc`` functions
 would and handles error conditions in the same way.
 
 
+Floating Point Environment Manipulation intrinsics
+--
+
+These functions read or write floating point environment, such as rounding
+mode or state of floating point exceptions. Altering the floating point
+environment requires special care. See :ref:`Floating Point Environment 
`.
+
+'``llvm.flt.rounds``' Intrinsic
+^^^
+
+Syntax:
+"""
+
+::
+
+  declare i32 @llvm.flt.rounds()
+
+Overview:
+"
+
+The '``llvm.flt.rounds``' intrinsic reads the current rounding mode.
+
+Semantics:
+""
+
+The '``llvm.flt.rounds``' intrinsic returns the current rounding mode.
+Encoding of the returned values is same as the result of ``FLT_ROUNDS``,
+specified by C standard:
+
+::
+
+0  - toward zero
+1  - to nearest, ties to even
+2  - toward positive infinity
+3  - toward negative infinity
+4  - to nearest, ties away from zero
+
+Other values may be used to represent additional rounding modes, supported by a
+target. These values are target-specific.
+
 General Intrinsics
 --
 

diff  --git a/llvm/include/llvm/IR/Intrinsics.td 
b/llvm/include/llvm/IR/Intrinsics.td
index dafa17959e82..51df06cee358 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -612,6 +612,13 @@ def int_objectsize : Intrinsic<[llvm_anyint_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, 
ImmArg<1>, ImmArg<2>, ImmArg<3>]>,
GCCBuiltin<"__builtin_object_size">;
 
+//===--- Access to Floating Point Environment 
-===//
+//
+
+let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
+  def int_flt_rounds: Intrinsic<[llvm_i32_ty], []>;
+}
+
 //===--- Constrained Floating Point Intrinsics 
===//
 //
 
@@ -1115,8 +1122,6 @@ def int_coro_subfn_addr : Intrinsic<[llvm_ptr_ty], 
[llvm_ptr_ty, llvm_i8_ty],
 
 ///===-- Other Intrinsics 
--===//
 //
-def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
- GCCBuiltin<"__builtin_flt_rounds">;
 def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold]>,
GCCBuiltin<"__builtin_trap">;
 def int_debugtrap : Intrinsic<[]>,



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


[clang] 21cd7b7 - Use typedef to represent storage type in FPOption and FPOptionsOverride

2020-07-21 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-07-21T14:35:50+07:00
New Revision: 21cd7b72a3d4d1d5efaadc09533655090b678e57

URL: 
https://github.com/llvm/llvm-project/commit/21cd7b72a3d4d1d5efaadc09533655090b678e57
DIFF: 
https://github.com/llvm/llvm-project/commit/21cd7b72a3d4d1d5efaadc09533655090b678e57.diff

LOG: Use typedef to represent storage type in FPOption and FPOptionsOverride

Size of FPOption is now 14 bit, which is closed to the current limit
of 16 bits. Adding new properties to FPOption would require change of
the types, which represent storage of FPOption and FPOptionsOverride.
To facilitate this change, the storage types were changed from standard
integer types to typedefs defined inside the proper classes. Checks for
size of these storage types were added.

No functional changes intended.

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

Added: 


Modified: 
clang/include/clang/Basic/FPOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
clang/include/clang/Serialization/ASTReader.h

Removed: 




diff  --git a/clang/include/clang/Basic/FPOptions.def 
b/clang/include/clang/Basic/FPOptions.def
index 6b6789b8ecc8..1733689775d4 100644
--- a/clang/include/clang/Basic/FPOptions.def
+++ b/clang/include/clang/Basic/FPOptions.def
@@ -7,7 +7,7 @@
 
//===--===//
 
 // This file defines the Floating Point language options. Users of this file
-//  must define the FPOPT macro to make use of this information.
+//  must define the OPTION macro to make use of this information.
 #ifndef OPTION
 #  error Define the OPTION macro to handle floating point language options
 #endif

diff  --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index a9213b7d8668..31e8af4589b4 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -374,6 +374,8 @@ class FPOptions {
 
   using RoundingMode = llvm::RoundingMode;
 
+  static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
+
   // Define a fake option named "First" so that we have a PREVIOUS even for the
   // real first option.
   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
@@ -385,6 +387,12 @@ class FPOptions {
  << NAME##Shift;
 #include "clang/Basic/FPOptions.def"
 
+  static constexpr storage_type TotalWidth = 0
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
+#include "clang/Basic/FPOptions.def"
+  ;
+  static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
+
 private:
   storage_type Value;
 
@@ -402,8 +410,8 @@ class FPOptions {
 setFPContractMode(LO.getDefaultFPContractMode());
 setRoundingMode(LO.getFPRoundingMode());
 setFPExceptionMode(LO.getFPExceptionMode());
-setAllowFEnvAccess(LangOptions::FPM_Off),
-setAllowFPReassociate(LO.AllowFPReassoc);
+setAllowFEnvAccess(LangOptions::FPM_Off);
+setAllowFPReassociate(LO.AllowFPReassoc);
 setNoHonorNaNs(LO.NoHonorNaNs);
 setNoHonorInfs(LO.NoHonorInfs);
 setNoSignedZero(LO.NoSignedZero);
@@ -453,18 +461,45 @@ class FPOptions {
   LLVM_DUMP_METHOD void dump();
 };
 
-/// The FPOptions override type is value of the new FPOptions
-///  plus a mask showing which fields are actually set in it:
+/// Represents 
diff erence between two FPOptions values.
+///
+/// The effect of language constructs changing the set of floating point 
options
+/// is usually a change of some FP properties while leaving others intact. This
+/// class describes such changes by keeping information about what FP options
+/// are overridden.
+///
+/// The integral set of FP options, described by the class FPOptions, may be
+/// represented as a default FP option set, defined by language standard and
+/// command line options, with the overrides introduced by pragmas.
+///
+/// The is implemented as a value of the new FPOptions plus a mask showing 
which
+/// fields are actually set in it.
 class FPOptionsOverride {
   FPOptions Options;
   FPOptions::storage_type OverrideMask = 0;
 
 public:
   using RoundingMode = llvm::RoundingMode;
+
+  /// The type suitable for storing values of FPOptionsOverride. Must be twice
+  /// as wide as bit size of FPOption.
+  using storage_type = uint32_t;
+  static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
+"Too short type for FPOptionsOverride");
+
+  /// Bit mask selecting bits of OverrideMask in serialized representation of
+  /// FPOptionsOverride.
+  static constexpr storage_type OverrideMaskBits =
+  (static_cast(1) << FPOptions::StorageBitSize) - 1;
+
   FPOptionsOverride() {}
+  FPOptionsOverride(FPOptions::storage_type Value, FPOptions::storage_type 
Mask)
+  : Options(Value), OverrideMask(Mask) {}
+  FPOptionsOverride(const LangOption

[Differential] D83772: [Windows] Fix limit on command line size

2020-07-21 Thread Serge Pavlov via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd4020ef7c474: [Windows] Fix limit on command line size 
(authored by sepavloff).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83772/new/


  https://reviews.llvm.org/D83772

Files:
  llvm/include/llvm/Support/Program.h
  llvm/lib/Support/Windows/Program.inc
  llvm/unittests/Support/CommandLineTest.cpp

Index: llvm/unittests/Support/CommandLineTest.cpp
===
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -763,6 +763,18 @@
 TEST(CommandLineTest, ArgumentLimit) {
   std::string args(32 * 4096, 'a');
   EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
+  std::string args2(256, 'a');
+  EXPECT_TRUE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args2.data()));
+  if (Triple(sys::getProcessTriple()).isOSWindows()) {
+// We use 32000 as a limit for command line length. Program name ('cl'),
+// separating spaces and termination null character occupy 5 symbols.
+std::string long_arg(32000 - 5, 'b');
+EXPECT_TRUE(
+llvm::sys::commandLineFitsWithinSystemLimits("cl", long_arg.data()));
+long_arg += 'b';
+EXPECT_FALSE(
+llvm::sys::commandLineFitsWithinSystemLimits("cl", long_arg.data()));
+  }
 }
 
 TEST(CommandLineTest, ResponseFileWindows) {
Index: llvm/lib/Support/Windows/Program.inc
===
--- llvm/lib/Support/Windows/Program.inc
+++ llvm/lib/Support/Windows/Program.inc
@@ -189,7 +189,14 @@
   // Windows wants a command line, not an array of args, to pass to the new
   // process.  We have to concatenate them all, while quoting the args that
   // have embedded spaces (or are empty).
-  std::string Command = flattenWindowsCommandLine(Args);
+  auto Result = flattenWindowsCommandLine(Args);
+  if (std::error_code ec = Result.getError()) {
+SetLastError(ec.value());
+MakeErrMsg(ErrMsg,
+   std::string("Unable to convert command-line to UTF-16"));
+return false;
+  }
+  std::wstring Command = *Result;
 
   // The pointer to the environment block for the new process.
   std::vector EnvBlock;
@@ -271,14 +278,8 @@
 return false;
   }
 
-  SmallVector CommandUtf16;
-  if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16)) {
-SetLastError(ec.value());
-MakeErrMsg(ErrMsg,
-   std::string("Unable to convert command-line to UTF-16"));
-return false;
-  }
-
+  std::vector CommandUtf16(Command.size() + 1, 0);
+  std::copy(Command.begin(), Command.end(), CommandUtf16.begin());
   BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0,
TRUE, CREATE_UNICODE_ENVIRONMENT,
EnvBlock.empty() ? 0 : EnvBlock.data(), 0, &si,
@@ -376,7 +377,7 @@
 }
 
 namespace llvm {
-std::string sys::flattenWindowsCommandLine(ArrayRef Args) {
+ErrorOr sys::flattenWindowsCommandLine(ArrayRef Args) {
   std::string Command;
   for (StringRef Arg : Args) {
 if (argNeedsQuotes(Arg))
@@ -387,7 +388,11 @@
 Command.push_back(' ');
   }
 
-  return Command;
+  SmallVector CommandUtf16;
+  if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16))
+return ec;
+
+  return std::wstring(CommandUtf16.begin(), CommandUtf16.end());
 }
 
 ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
@@ -532,12 +537,16 @@
 
 bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
   ArrayRef Args) {
-  // The documented max length of the command line passed to CreateProcess.
-  static const size_t MaxCommandStringLength = 32768;
+  // The documentation on CreateProcessW states that the size of the argument
+  // lpCommandLine must not be greater than 32767 characters, including the
+  // Unicode terminating null character. We use smaller value to reduce risk
+  // of getting invalid command line due to unaccounted factors.
+  static const size_t MaxCommandStringLength = 32000;
   SmallVector FullArgs;
   FullArgs.push_back(Program);
   FullArgs.append(Args.begin(), Args.end());
-  std::string Result = flattenWindowsCommandLine(FullArgs);
-  return (Result.size() + 1) <= MaxCommandStringLength;
+  auto Result = flattenWindowsCommandLine(FullArgs);
+  assert(!Result.getError());
+  return (Result->size() + 1) <= MaxCommandStringLength;
 }
 }
Index: llvm/include/llvm/Support/Program.h
===
--- llvm/include/llvm/Support/Program.h
+++ llvm/include/llvm/Support/Program.h
@@ -218,7 +218,7 @@
   /// to build a single flat command line appropriate for calling CreateProcess
   /// on
   /// Windows.
-  std::string flattenWindowsCommandLine(ArrayRef Args);
+  ErrorOr flattenWindowsCommandLine(ArrayRef Args);
 #e

[clang] 70e7aa4 - [AST][FPEnv] Keep FP options in trailing storage of CallExpr

2020-07-23 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-07-24T12:04:19+07:00
New Revision: 70e7aa4a4ed36a034c43b249d0842f4f273b44e1

URL: 
https://github.com/llvm/llvm-project/commit/70e7aa4a4ed36a034c43b249d0842f4f273b44e1
DIFF: 
https://github.com/llvm/llvm-project/commit/70e7aa4a4ed36a034c43b249d0842f4f273b44e1.diff

LOG: [AST][FPEnv] Keep FP options in trailing storage of CallExpr

This change allow a CallExpr to have optional FPOptionsOverride object,
stored in trailing storage. The implementaion is made similar to the way
used in BinaryOperator.

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

Added: 
clang/test/AST/ast-dump-fpfeatures.cpp

Modified: 
clang/include/clang/AST/Expr.h
clang/include/clang/AST/ExprCXX.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
clang/lib/Frontend/Rewrite/RewriteObjC.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 24bface15d3e..96db7bc3be29 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2272,12 +2272,12 @@ class UnaryOperator final
   /// Is FPFeatures in Trailing Storage?
   bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; }
 
-protected:
-  /// Get FPFeatures from trailing storage
+  /// Get FPFeatures from trailing storage.
   FPOptionsOverride getStoredFPFeatures() const {
 return getTrailingFPFeatures();
   }
 
+protected:
   /// Set FPFeatures in trailing storage, used only by Serialization
   void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; 
}
 
@@ -2787,6 +2787,8 @@ class CallExpr : public Expr {
   //
   // * An array of getNumArgs() "Stmt *" for the argument expressions.
   //
+  // * An optional of type FPOptionsOverride.
+  //
   // Note that we store the offset in bytes from the this pointer to the start
   // of the trailing objects. It would be perfectly possible to compute it
   // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
@@ -2808,6 +2810,15 @@ class CallExpr : public Expr {
   /// this pointer to the trailing objects.
   static unsigned offsetToTrailingObjects(StmtClass SC);
 
+  unsigned getSizeOfTrailingStmts() const {
+return (1 + getNumPreArgs() + getNumArgs()) * sizeof(Stmt *);
+  }
+
+  size_t getOffsetOfTrailingFPFeatures() const {
+assert(hasStoredFPFeatures());
+return CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStmts();
+  }
+
 public:
   enum class ADLCallKind : bool { NotADL, UsesADL };
   static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
@@ -2818,16 +2829,19 @@ class CallExpr : public Expr {
   /// allocated for the trailing objects.
   CallExpr(StmtClass SC, Expr *Fn, ArrayRef PreArgs,
ArrayRef Args, QualType Ty, ExprValueKind VK,
-   SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+   SourceLocation RParenLoc, FPOptionsOverride FPFeatures,
+   unsigned MinNumArgs, ADLCallKind UsesADL);
 
   /// Build an empty call expression, for deserialization.
   CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
-   EmptyShell Empty);
+   bool hasFPFeatures, EmptyShell Empty);
 
   /// Return the size in bytes needed for the trailing objects.
   /// Used by the derived classes to allocate the right amount of storage.
-  static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) 
{
-return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
+  static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs,
+bool HasFPFeatures) {
+return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *) +
+   HasFPFeatures * sizeof(FPOptionsOverride);
   }
 
   Stmt *getPreArg(unsigned I) {
@@ -2845,22 +2859,43 @@ class CallExpr : public Expr {
 
   unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
 
+  /// Return a pointer to the trailing FPOptions
+  FPOptionsOverride *getTrailingFPFeatures() {
+assert(hasStoredFPFeatures());
+return reinterpret_cast(
+reinterpret_cast(this) + CallExprBits.OffsetToTrailingObjects +
+getSizeOfTrailingStmts());
+  }
+  const FPOptionsOverride *getTrailingFPFeatures() const {
+assert(hasStoredFPFeatures());
+return reinterpret_cast(
+reinterpret_cast(this) +
+CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStm

[clang] c7ff5b3 - [FPEnv] Use single enum to represent rounding mode

2020-04-08 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-04-09T13:26:47+07:00
New Revision: c7ff5b38f27f812dcd6e2e8732208a39232dc284

URL: 
https://github.com/llvm/llvm-project/commit/c7ff5b38f27f812dcd6e2e8732208a39232dc284
DIFF: 
https://github.com/llvm/llvm-project/commit/c7ff5b38f27f812dcd6e2e8732208a39232dc284.diff

LOG: [FPEnv] Use single enum to represent rounding mode

Now compiler defines 5 sets of constants to represent rounding mode.
These are:

1. `llvm::APFloatBase::roundingMode`. It specifies all 5 rounding modes
defined by IEEE-754 and is used in `APFloat` implementation.

2. `clang::LangOptions::FPRoundingModeKind`. It specifies 4 of 5 IEEE-754
rounding modes and a special value for dynamic rounding mode. It is used
in clang frontend.

3. `llvm::fp::RoundingMode`. Defines the same values as
`clang::LangOptions::FPRoundingModeKind` but in different order. It is
used to specify rounding mode in in IR and functions that operate IR.

4. Rounding mode representation used by `FLT_ROUNDS` (C11, 5.2.4.2.2p7).
Besides constants for rounding mode it also uses a special value to
indicate error. It is convenient to use in intrinsic functions, as it
represents platform-independent representation for rounding mode. In this
role it is used in some pending patches.

5. Values like `FE_DOWNWARD` and other, which specify rounding mode in
library calls `fesetround` and `fegetround`. Often they represent bits
of some control register, so they are target-dependent. The same names
(not values) and a special name `FE_DYNAMIC` are used in
`#pragma STDC FENV_ROUND`.

The first 4 sets of constants are target independent and could have the
same numerical representation. It would simplify conversion between the
representations. Also now `clang::LangOptions::FPRoundingModeKind` and
`llvm::fp::RoundingMode` do not contain the value for IEEE-754 rounding
direction `roundTiesToAway`, although it is supported natively on
some targets.

This change defines all the rounding mode type via one `llvm::RoundingMode`,
which also contains rounding mode for IEEE rounding direction `roundTiesToAway`.

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

Added: 


Modified: 
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Serialization/ASTReader.cpp
llvm/docs/LangRef.rst
llvm/include/llvm/ADT/APFloat.h
llvm/include/llvm/ADT/FloatingPointMode.h
llvm/include/llvm/IR/FPEnv.h
llvm/include/llvm/IR/IRBuilder.h
llvm/include/llvm/IR/IntrinsicInst.h
llvm/lib/Analysis/ConstantFolding.cpp
llvm/lib/IR/FPEnv.cpp
llvm/lib/IR/IRBuilder.cpp
llvm/lib/IR/IntrinsicInst.cpp
llvm/lib/Support/APFloat.cpp
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/unittests/IR/IRBuilderTest.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 51dc87b0b671..bddd0f0ddcd8 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -263,7 +263,7 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating 
double-precision floating poi
 LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
 /// FP_CONTRACT mode (on/off/fast).
 ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP 
contraction type")
-ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP 
Rounding Mode type")
+ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, 
"FP Rounding Mode type")
 ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP 
Exception Behavior Mode type")
 LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
 LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")

diff  --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 0a0cbaf80ae8..95b435ba9f34 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -19,6 +19,7 @@
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/Visibility.h"
+#include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include 
@@ -53,6 +54,7 @@ enum class MSVtorDispMode { Never, ForVBaseOverride, 
ForVFTable };
 class LangOptions : public LangOptionsBase {
 public:
   using Visibility = clang::Visibility;
+  using RoundingMode = llvm::RoundingMode;
 
   enum GCMode { NonGC, GCOnly, HybridGC };
   enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
@@ -190,23 +192,9 @@ class LangOptions : public LangOptionsBase {
 FEA_On
   };
 
-  // Values of the following enumerations correspond to 

[PATCH] D24917: Resolve response file names relative to including file

2016-09-26 Thread Serge Pavlov via cfe-commits
sepavloff created this revision.
sepavloff added a reviewer: rnk.
sepavloff added a subscriber: cfe-commits.

If a response file included by construct @file itself includes a response file
and that file is specified by relative file name, resolve the name relative
to the including file.  With this behavior a set of related response files may
be kept together and reference each other with short position-independent names.
This is convenient for implementation of configuration files.

https://reviews.llvm.org/D24917

Files:
  lib/Support/CommandLine.cpp
  unittests/Support/CommandLineTest.cpp

Index: unittests/Support/CommandLineTest.cpp
===
--- unittests/Support/CommandLineTest.cpp
+++ unittests/Support/CommandLineTest.cpp
@@ -7,11 +7,15 @@
 //
 //===--===//
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/StringSaver.h"
 #include "gtest/gtest.h"
+#include 
 #include 
 #include 
 
@@ -476,4 +480,64 @@
   EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
 }
 
+TEST(CommandLineTest, ResponseFiles) {
+  llvm::SmallString<128> TestDir;
+  std::error_code EC =
+llvm::sys::fs::createUniqueDirectory("unittest", TestDir);
+  EXPECT_TRUE(!EC);
+
+  // Create included response file of first level.
+  llvm::SmallString<128> IncludedFileName;
+  llvm::sys::path::append(IncludedFileName, TestDir, "resp1");
+  std::ofstream IncludedFile(IncludedFileName.c_str());
+  EXPECT_TRUE(IncludedFile.is_open());
+  IncludedFile << "-option_1 -option_2\n"
+  "@incdir/resp2\n"
+  "-option_3=abcd\n";
+  IncludedFile.close();
+
+  // Directory for included file.
+  llvm::SmallString<128> IncDir;
+  llvm::sys::path::append(IncDir, TestDir, "incdir");
+  EC = llvm::sys::fs::create_directory(IncDir);
+  EXPECT_TRUE(!EC);
+
+  // Create included response file of second level.
+  llvm::SmallString<128> IncludedFileName2;
+  llvm::sys::path::append(IncludedFileName2, IncDir, "resp2");
+  std::ofstream IncludedFile2(IncludedFileName2.c_str());
+  EXPECT_TRUE(IncludedFile2.is_open());
+  IncludedFile2 << "-option_21 -option_22\n";
+  IncludedFile2 << "-option_23=abcd\n";
+  IncludedFile2.close();
+
+  // Prepare 'file' with reference to response file.
+  SmallString<128> IncRef;
+  IncRef.append(1, '@');
+  IncRef.append(IncludedFileName.c_str());
+  llvm::SmallVector Argv =
+{ "test/test", "-flag_1", IncRef.c_str(), "-flag_2" };
+
+  // Expand response files.
+  llvm::BumpPtrAllocator A;
+  llvm::StringSaver Saver(A);
+  bool Res = llvm::cl::ExpandResponseFiles(
+ Saver, llvm::cl::TokenizeGNUCommandLine, Argv);
+  EXPECT_TRUE(Res);
+  EXPECT_EQ(Argv.size(), 9);
+  EXPECT_STREQ(Argv[0], "test/test");
+  EXPECT_STREQ(Argv[1], "-flag_1");
+  EXPECT_STREQ(Argv[2], "-option_1");
+  EXPECT_STREQ(Argv[3], "-option_2");
+  EXPECT_STREQ(Argv[4], "-option_21");
+  EXPECT_STREQ(Argv[5], "-option_22");
+  EXPECT_STREQ(Argv[6], "-option_23=abcd");
+  EXPECT_STREQ(Argv[7], "-option_3=abcd");
+  EXPECT_STREQ(Argv[8], "-flag_2");
+
+  llvm::sys::fs::remove(IncludedFileName2);
+  llvm::sys::fs::remove(IncDir);
+  llvm::sys::fs::remove(IncludedFileName);
+}
+
 }  // anonymous namespace
Index: lib/Support/CommandLine.cpp
===
--- lib/Support/CommandLine.cpp
+++ lib/Support/CommandLine.cpp
@@ -865,7 +865,7 @@
   return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
 }
 
-static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
+static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
TokenizerCallback Tokenizer,
SmallVectorImpl &NewArgv,
bool MarkEOLs = false) {
@@ -893,6 +893,25 @@
   // Tokenize the contents into NewArgv.
   Tokenizer(Str, Saver, NewArgv, MarkEOLs);
 
+  // Scan expanded arguments. If any of them is itself an expansion of a
+  // response file and that file was specified by relative name, replace the
+  // response file name with the full path obtained by resolution of the
+  // specified name relative to the path of current file.
+  for (unsigned I = 0; I < NewArgv.size(); ++I)
+if (NewArgv[I]) {
+  StringRef Arg = NewArgv[I];
+  if (Arg.front() == '@') {
+StringRef FileName = Arg.drop_front();
+if (llvm::sys::path::is_relative(FileName)) {
+  SmallString<128> ResponseFile;
+  ResponseFile.append(1, '@');
+  llvm::sys::path::append(ResponseFile,
+  llvm::sys::path::parent_path(FName), FileName);
+  NewArgv[I] = Saver.save(R

[PATCH] D24933: Enable configuration files in clang

2016-09-26 Thread Serge Pavlov via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: rnk, ddunbar.
sepavloff added a subscriber: cfe-commits.

The implementation follows the discussion in mail list
(http://lists.llvm.org/pipermail/cfe-dev/2016-September/050776.html).
Main part of the config file support is implemented in llvm source tree,
in CommandLine library, see D24926 and D24917.

https://reviews.llvm.org/D24933

Files:
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/Inputs/config-1.cfg
  test/Driver/Inputs/config-2.cfg
  test/Driver/config-file.c
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -330,6 +330,14 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
 
+  // Try reading options from configuration file.
+  static const char * const SearchDirs[] = { "~/.llvm", "/etc/llvm" };
+  llvm::SmallString<128> ConfigFile;
+  auto SRes = llvm::cl::findConfigFile(ConfigFile, argv, SearchDirs, "clang");
+  llvm::cl::reportConfigFileSearchError(SRes, ConfigFile, SearchDirs, ProgName);
+  if (SRes == llvm::cl::CfgFileSearch::Successful)
+llvm::cl::readConfigFile(ConfigFile, Saver, argv);
+
   // Parse response files using the GNU syntax, unless we're in CL mode. There
   // are two ways to put clang in CL compatibility mode: argv[0] is either
   // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
@@ -446,6 +454,8 @@
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
+  if (!ConfigFile.empty())
+TheDriver.setConfigFile(ConfigFile.str());
   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
 
   insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv,
Index: test/Driver/config-file.c
===
--- /dev/null
+++ test/Driver/config-file.c
@@ -0,0 +1,30 @@
+// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH
+// CHECK-HHH: Target: x86_64-apple-darwin
+// CHECK-HHH: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-HHH: -Werror
+// CHECK-HHH: -std=c99
+
+// RUN: not %clang --config %S/Inputs/inexistent.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-INEX
+// CHECK-INEX: Configuration file {{.*}}/Inputs/inexistent.cfg' specified by option '--config' cannot be found
+
+// RUN: not %clang --config inexistent.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-INEX-NOSEARCH
+// CHECK-INEX-NOSEARCH: Configuration {{.*}}inexistent.cfg' specified by option '--config' cannot be found in directories:
+// CHECK-INEX-NOSEARCH: ~/.llvm
+// CHECK-INEX-NOSEARCH: /etc/llvm
+
+// RUN: %clang --config %S/Inputs/config-2.cfg -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH-NOFILE
+// CHECK-HHH-NOFILE: Target: x86_64-unknown-linux
+// CHECK-HHH-NOFILE: Configuration file: {{.*}}/Inputs/config-2.cfg
+
+// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -v 2>&1 | FileCheck %s -check-prefix CHECK-V
+// CHECK-V: Target: x86_64-apple-darwin
+// CHECK-V: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-V: -triple{{.*}}x86_64-apple-
+
+// RUN: env CLANGCFG=%S/Inputs/config-1.cfg %clang -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-ENV
+// CHECK-ENV: Target: x86_64-apple-darwin
+// CHECK-ENV: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-ENV: -Werror
+
+// RUN: env CLANGCFG=inexistent.cfg not %clang -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-ENV-INEX
+// CHECK-ENV-INEX: Configuration file 'inexistent.cfg' specified by environment variable cannot be found
Index: test/Driver/Inputs/config-2.cfg
===
--- /dev/null
+++ test/Driver/Inputs/config-2.cfg
@@ -0,0 +1,2 @@
+# target
+-target x86_64-unknown-linux-gnu
Index: test/Driver/Inputs/config-1.cfg
===
--- /dev/null
+++ test/Driver/Inputs/config-1.cfg
@@ -0,0 +1,7 @@
+
+
+# Empty lines and line started with # are ignored
+-Werror -std=\
+c99
+# Target
+-target x86_64-apple-darwin
\ No newline at end of file
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -895,6 +895,10 @@
 
   // Print out the install directory.
   OS << "InstalledDir: " << InstalledDir << '\n';
+
+  // If configuration file was used, print its path.
+  if (!ConfigFile.empty())
+OS << "Configuration file: " << ConfigFile << '\n';
 }
 
 /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories
Index: include/clang/Driver/Driver.h
===
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -187,6 +187,9 @@
   /// Name to use when invoking gcc/g++.
   std::string

[PATCH] D24933: Enable configuration files in clang

2016-10-03 Thread Serge Pavlov via cfe-commits
sepavloff updated this revision to Diff 73245.
sepavloff added a comment.

Updated path

The patch is aligned with corresponding changes in llvm repository 
(https://reviews.llvm.org/D24926).
Also support of configuration selection for executables line foo-clang is
added.


https://reviews.llvm.org/D24933

Files:
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/Inputs/config-1.cfg
  test/Driver/Inputs/config-2.cfg
  test/Driver/config-file.c
  test/Driver/config-file2.c
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -305,6 +305,28 @@
   return 1;
 }
 
+// Directories searched for configuration specified by option '--config'.
+static const ArrayRef SearchDirs({ "~/.llvm", "/etc/llvm" });
+
+// Directories searched for default configuration.
+static const ArrayRef DefSearchDirs;
+
+static llvm::cl::SearchResult findConfigFileFromProgramName(
+llvm::SmallVectorImpl &ConfigName, StringRef ProgramName) {
+  ConfigName.clear();
+  StringRef PName = llvm::sys::path::stem(ProgramName);
+  size_t Pos = PName.find("-clang");
+  if (Pos != StringRef::npos) {
+ConfigName.append(PName.begin(), PName.begin() + Pos);
+const StringRef Ext(".cfg");
+ConfigName.append(Ext.begin(), Ext.end());
+std::string CName(ConfigName.begin(), ConfigName.size());
+return llvm::cl::findDefaultCfgFile(ConfigName, DefSearchDirs, ProgramName,
+CName);
+  }
+  return llvm::cl::SearchResult::NotSpecified;
+}
+
 int main(int argc_, const char **argv_) {
   llvm::sys::PrintStackTraceOnErrorSignal(argv_[0]);
   llvm::PrettyStackTraceProgram X(argc_, argv_);
@@ -330,6 +352,47 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
 
+  // Try reading options from configuration file.
+  llvm::SmallString<128> ConfigFile;
+
+  // First try config file specified in command line. It has higher priority
+  // than any other way to specify configuration.
+  auto SRes = llvm::cl::findConfigFileFromArgs(ConfigFile, argv, SearchDirs);
+  if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, SearchDirs,
+ProgName))
+return 1;
+
+  // Environment variable has the next priority. It also specifies config file
+  // explicitly.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = llvm::cl::findConfigFileFromEnv(ConfigFile, "CLANGCFG");
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, SearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  // If config file is not specified explicitly, try determine configuration
+  // implicitly. First try deduce configuration from executable. For instance,
+  // file 'armv7l-clang' applies config file 'armv7l.cfg'.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = findConfigFileFromProgramName(ConfigFile, ProgName);
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, DefSearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  // Finally try to find file 'clang.cfg'.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = llvm::cl::findDefaultCfgFile(ConfigFile, DefSearchDirs, ProgName,
+"clang.cfg");
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, DefSearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  if (SRes == llvm::cl::SearchResult::Successful)
+llvm::cl::readConfigFile(ConfigFile, Saver, argv);
+
   // Parse response files using the GNU syntax, unless we're in CL mode. There
   // are two ways to put clang in CL compatibility mode: argv[0] is either
   // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
@@ -446,6 +509,8 @@
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
+  if (!ConfigFile.empty())
+TheDriver.setConfigFile(ConfigFile.str());
   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
 
   insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv,
Index: test/Driver/config-file2.c
===
--- /dev/null
+++ test/Driver/config-file2.c
@@ -0,0 +1,13 @@
+// Due to ln -sf:
+// REQUIRES: shell
+
+// RUN: mkdir -p %t.cfgtest
+// RUN: PWD=`pwd`
+// RUN: cd %t.cfgtest
+// RUN: ln -sf %clang test123-clang
+// RUN: echo "-ferror-limit=666" > test123.cfg
+// RUN: cd $PWD
+// RUN: %t.cfgtest/test123-clang -v -c %s -o - 2>&1 | FileCheck %s
+
+// CHECK: Configuration file:{{.*}}test123.cfg
+// CHECK: -ferror-limit{{.*}}666
Index: test/Driver/config-file.c
===
--- /dev/null
+++ test/Driver/config-file.c
@@ -0,0 +1,30 @@
+// RUN: %clang --config 

[PATCH] D24933: Enable configuration files in clang

2016-10-03 Thread Serge Pavlov via cfe-commits
sepavloff added inline comments.


> mgorny wrote in driver.cpp:334
> 1. I'm not sure if others would agree with me but I think it would be better 
> to move those default paths straight to LLVM. If others tools are to adopt 
> those configuration files, it would only be reasonable to use the same search 
> paths consistently and not repeat them in every tool.
> 
> 2. I think the `/etc` prefix should be made configurable via CMake options. 
> One case that would benefit from this is Gentoo Prefix where the Gentoo 
> system root is located in a subdirectory of /.

It make sense, as it would establish uniform paths. However CommandLine is 
positioned as general purpose library, which can be used by any tool, not only 
llvm ones, so forcing particular paths seems to be too rigid. Besides, 
discussion in mail list demonstrated very diverse opinions, so I would prefer 
flexible solution.

Notion about configurable paths is definitely worth implementing.

> mgorny wrote in driver.cpp:336
> 1. You need to update this, following your update on 
> https://reviews.llvm.org/D24926.
> 2. I think you need to use `clang.cfg` here.

Updated, thank you.

https://reviews.llvm.org/D24933



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


Re: [PATCH] D16989: Change interpretation of function definition in friend declaration of template class.

2016-10-03 Thread Serge Pavlov via cfe-commits
Ping.

Thanks,
--Serge

2016-09-16 23:17 GMT+07:00 Serge Pavlov :

> Ping.
>
> Thanks,
> --Serge
>
> 2016-09-08 20:43 GMT+07:00 Serge Pavlov :
>
>> Any feedback?
>>
>> Thanks,
>> --Serge
>>
>> 2016-09-02 13:11 GMT+07:00 Serge Pavlov :
>>
>>> sepavloff updated this revision to Diff 70134.
>>> sepavloff marked an inline comment as done.
>>> sepavloff added a comment.
>>>
>>> Updated patch
>>>
>>> Rewrite the condition in shouldLinkDependentDeclWithPrevious in more
>>> compact form.
>>>
>>>
>>> https://reviews.llvm.org/D16989
>>>
>>> Files:
>>>   include/clang/Sema/Sema.h
>>>   lib/Sema/SemaDecl.cpp
>>>   lib/Sema/SemaDeclCXX.cpp
>>>   test/SemaCXX/PR25848.cpp
>>>   test/SemaCXX/friend2.cpp
>>>   test/SemaCXX/function-redecl-2.cpp
>>>
>>>
>>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r283207 - Do not find friend function definitions inside non-instantiated class.

2016-10-04 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Tue Oct  4 05:11:43 2016
New Revision: 283207

URL: http://llvm.org/viewvc/llvm-project?rev=283207&view=rev
Log:
Do not find friend function definitions inside non-instantiated class.

Previously if a file-level function was defined inside befriending
template class, it always was treated as defined. For instance, the code like:
```
  int func(int x);
  template class C1 {
friend int func(int x) { return x; }
  };
  template class C2 {
friend int func(int x) { return x; }
  };
```
could not be compiled due to function redefinition, although not of the 
templates
is instantiated. Moreover, the body of friend function can contain use of 
template
parameters, attempt to get definition of such function outside any instantiation
causes compiler abnormal termination.

Other compilers (gcc, icc) follow viewpoint that the body of the function 
defined
in friend declaration becomes available when corresponding class is 
instantiated.
This patch implements this viewpoint in clang.

Definitions introduced by friend declarations in template classes are not added
to the redeclaration chain of corresponding function. Only when the template is
instantiated, instantiation of the function definition is placed to the chain.

The fix was made in collaboration with Richard Smith.

This change fixes PR8035, PR17923, PR22307 and PR25848.

Differential Revision: http://reviews.llvm.org/D16989

Added:
cfe/trunk/test/SemaCXX/PR25848.cpp
cfe/trunk/test/SemaCXX/friend2.cpp
cfe/trunk/test/SemaCXX/function-redecl-2.cpp
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=283207&r1=283206&r2=283207&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Oct  4 05:11:43 2016
@@ -1760,6 +1760,7 @@ public:
   bool CheckFunctionDeclaration(Scope *S,
 FunctionDecl *NewFD, LookupResult &Previous,
 bool IsExplicitSpecialization);
+  bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
   void CheckMain(FunctionDecl *FD, const DeclSpec &D);
   void CheckMSVCRTEntryPoint(FunctionDecl *FD);
   Decl *ActOnParamDeclarator(Scope *S, Declarator &D);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=283207&r1=283206&r2=283207&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct  4 05:11:43 2016
@@ -8664,6 +8664,32 @@ Sema::ActOnFunctionDeclarator(Scope *S,
   return NewFD;
 }
 
+/// \brief Checks if the new declaration declared in dependent context must be
+/// put in the same redeclaration chain as the specified declaration.
+///
+/// \param D Declaration that is checked.
+/// \param PrevDecl Previous declaration found with proper lookup method for 
the
+/// same declaration name.
+/// \returns True if D must be added to the redeclaration chain which PrevDecl
+///  belongs to.
+///
+bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) {
+  // Any declarations should be put into redeclaration chains except for
+  // friend declaration in a dependent context that names a function in
+  // namespace scope.
+  //
+  // This allows to compile code like:
+  //
+  //   void func();
+  //   template class C1 { friend void func() { } };
+  //   template class C2 { friend void func() { } };
+  //
+  // This code snippet is a valid code unless both templates are instantiated.
+  return !(D->getLexicalDeclContext()->isDependentContext() &&
+   D->getDeclContext()->isFileContext() &&
+   D->getFriendObjectKind() != Decl::FOK_None);
+}
+
 /// \brief Perform semantic checking of a new function declaration.
 ///
 /// Performs semantic analysis of the new function declaration
@@ -8847,11 +8873,14 @@ bool Sema::CheckFunctionDeclaration(Scop
   }
 
 } else {
-  // This needs to happen first so that 'inline' propagates.
-  NewFD->setPreviousDeclaration(cast(OldDecl));
-
-  if (isa(NewFD))
-NewFD->setAccess(OldDecl->getAccess());
+  if (shouldLinkDependentDeclWithPrevious(NewFD, OldDecl)) {
+// This needs to happen first so that 'inline' propagates.
+NewFD->setPreviousDeclaration(cast(OldDecl));
+if (isa(NewFD))
+  NewFD->setAccess(OldDecl->getAccess());
+  } else {
+Redeclaration = false;
+  }
 }
   }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=283207&r1=283206&r2=283207&view=diff
=

[PATCH] D16989: Change interpretation of function definition in friend declaration of template class.

2016-10-04 Thread Serge Pavlov via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL283207: Do not find friend function definitions inside 
non-instantiated class. (authored by sepavloff).

Changed prior to commit:
  https://reviews.llvm.org/D16989?vs=70134&id=73440#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D16989

Files:
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp
  cfe/trunk/test/SemaCXX/PR25848.cpp
  cfe/trunk/test/SemaCXX/friend2.cpp
  cfe/trunk/test/SemaCXX/function-redecl-2.cpp

Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -1760,6 +1760,7 @@
   bool CheckFunctionDeclaration(Scope *S,
 FunctionDecl *NewFD, LookupResult &Previous,
 bool IsExplicitSpecialization);
+  bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
   void CheckMain(FunctionDecl *FD, const DeclSpec &D);
   void CheckMSVCRTEntryPoint(FunctionDecl *FD);
   Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
Index: cfe/trunk/test/SemaCXX/PR25848.cpp
===
--- cfe/trunk/test/SemaCXX/PR25848.cpp
+++ cfe/trunk/test/SemaCXX/PR25848.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A;
+
+inline int g();  // expected-warning{{inline function 'g' is not defined}}
+
+template
+struct R {
+  friend int g() {
+return M;
+  }
+};
+
+void m() {
+  g();  // expected-note{{used here}}
+}
Index: cfe/trunk/test/SemaCXX/function-redecl-2.cpp
===
--- cfe/trunk/test/SemaCXX/function-redecl-2.cpp
+++ cfe/trunk/test/SemaCXX/function-redecl-2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace redecl_in_templ {
+template void redecl_in_templ() {
+  extern void func_1();  // expected-note  {{previous declaration is here}}
+  extern int  func_1();  // expected-error {{functions that differ only in their return type cannot be overloaded}}
+}
+
+void g();
+constexpr void (*p)() = g;
+
+template struct X {};
+template<> struct X { typedef int type; };
+
+template void f() {
+  extern void g();
+  X<&g == p>::type n;
+}
+}
Index: cfe/trunk/test/SemaCXX/friend2.cpp
===
--- cfe/trunk/test/SemaCXX/friend2.cpp
+++ cfe/trunk/test/SemaCXX/friend2.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+// If a friend function is defined in several non-template classes,
+// it is an error.
+
+void func1(int);
+struct C1a {
+  friend void func1(int) {}  // expected-note{{previous definition is here}}
+};
+struct C1b {
+  friend void func1(int) {}  // expected-error{{redefinition of 'func1'}}
+};
+
+
+// If a friend function is defined in both non-template and template
+// classes it is an error only if the template is instantiated.
+
+void func2(int);
+struct C2a {
+  friend void func2(int) {}
+};
+template struct C2b {
+  friend void func2(int) {}
+};
+
+void func3(int);
+struct C3a {
+  friend void func3(int) {}  // expected-note{{previous definition is here}}
+};
+template struct C3b {
+  friend void func3(int) {}  // expected-error{{redefinition of 'func3'}}
+};
+C3b c3;  // expected-note{{in instantiation of template class 'C3b' requested here}}
+
+
+// If a friend function is defined in several template classes it is an error
+// only if several templates are instantiated.
+
+void func4(int);
+template struct C4a {
+  friend void func4(int) {}
+};
+template struct C4b {
+  friend void func4(int) {}
+};
+
+
+void func5(int);
+template struct C5a {
+  friend void func5(int) {}
+};
+template struct C5b {
+  friend void func5(int) {}
+};
+C5a c5a;
+
+void func6(int);
+template struct C6a {
+  friend void func6(int) {}  // expected-note{{previous definition is here}}
+};
+template struct C6b {
+  friend void func6(int) {}  // expected-error{{redefinition of 'func6'}}
+};
+C6a c6a;
+C6b c6b;  // expected-note{{in instantiation of template class 'C6b' requested here}}
+
+void func7(int);
+template struct C7 {
+  friend void func7(int) {}  // expected-error{{redefinition of 'func7'}}
+ // expected-note@-1{{previous definition is here}}
+};
+C7 c7a;
+C7 c7b;  // expected-note{{in instantiation of template class 'C7' requested here}}
+
+
+// Even if clases are not instantiated and hence friend functions defined in them are not
+// available, their declarations can be checked.
+
+void func8(int);  // expected-note{{previous declaration is here}}
+template struct C8a {
+  friend long func8(int);  // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void func9(int);  // expected-note{{previous declaration is here}}
+template

[PATCH] D24933: Enable configuration files in clang

2016-10-04 Thread Serge Pavlov via cfe-commits
sepavloff updated this revision to Diff 73482.
sepavloff added a comment.

Updated comments.


https://reviews.llvm.org/D24933

Files:
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/Inputs/config-1.cfg
  test/Driver/Inputs/config-2.cfg
  test/Driver/config-file.c
  test/Driver/config-file2.c
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -305,6 +305,36 @@
   return 1;
 }
 
+// Directories searched for configuration specified by option '--config'.
+static const ArrayRef SearchDirs({ "~/.llvm", "/etc/llvm" });
+
+// Directories searched for default configuration.
+static const ArrayRef DefSearchDirs;
+
+/// \brief Tries to find config file based on executable name.
+///
+/// If clang executable has name like foo-clang, the function tries to find file
+/// foo.cfg. The search is made by same rules as for default config file.
+///
+/// \param ConfigName  [out] File name, if the search is successful.
+/// \param ProgramName [in]  Clang executable name.
+///
+static llvm::cl::SearchResult findConfigFileFromProgramName(
+llvm::SmallVectorImpl &ConfigName, StringRef ProgramName) {
+  ConfigName.clear();
+  StringRef PName = llvm::sys::path::stem(ProgramName);
+  size_t Pos = PName.find("-clang");
+  if (Pos != StringRef::npos) {
+ConfigName.append(PName.begin(), PName.begin() + Pos);
+const StringRef Ext(".cfg");
+ConfigName.append(Ext.begin(), Ext.end());
+std::string CName(ConfigName.begin(), ConfigName.size());
+return llvm::cl::findDefaultCfgFile(ConfigName, DefSearchDirs, ProgramName,
+CName);
+  }
+  return llvm::cl::SearchResult::NotSpecified;
+}
+
 int main(int argc_, const char **argv_) {
   llvm::sys::PrintStackTraceOnErrorSignal(argv_[0]);
   llvm::PrettyStackTraceProgram X(argc_, argv_);
@@ -330,6 +360,47 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
 
+  // Try reading options from configuration file.
+  llvm::SmallString<128> ConfigFile;
+
+  // First try config file specified in command line. It has higher priority
+  // than any other way to specify configuration.
+  auto SRes = llvm::cl::findConfigFileFromArgs(ConfigFile, argv, SearchDirs);
+  if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, SearchDirs,
+ProgName))
+return 1;
+
+  // Environment variable has the next priority. It also specifies config file
+  // explicitly.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = llvm::cl::findConfigFileFromEnv(ConfigFile, "CLANGCFG");
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, SearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  // If config file is not specified explicitly, try determine configuration
+  // implicitly. First try deduce configuration from executable. For instance,
+  // file 'foo-clang' applies config file 'foo.cfg'.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = findConfigFileFromProgramName(ConfigFile, ProgName);
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, DefSearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  // Finally try to find file 'clang.cfg'.
+  if (SRes == llvm::cl::SearchResult::NotSpecified) {
+SRes = llvm::cl::findDefaultCfgFile(ConfigFile, DefSearchDirs, ProgName,
+"clang.cfg");
+if (llvm::cl::checkConfigFileSearchResult(SRes, ConfigFile, DefSearchDirs,
+  ProgName))
+  return 1;
+  }
+
+  if (SRes == llvm::cl::SearchResult::Successful)
+llvm::cl::readConfigFile(ConfigFile, Saver, argv);
+
   // Parse response files using the GNU syntax, unless we're in CL mode. There
   // are two ways to put clang in CL compatibility mode: argv[0] is either
   // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
@@ -446,6 +517,8 @@
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
+  if (!ConfigFile.empty())
+TheDriver.setConfigFile(ConfigFile.str());
   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
 
   insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv,
Index: test/Driver/config-file2.c
===
--- /dev/null
+++ test/Driver/config-file2.c
@@ -0,0 +1,13 @@
+// Due to ln -sf:
+// REQUIRES: shell
+
+// RUN: mkdir -p %t.cfgtest
+// RUN: PWD=`pwd`
+// RUN: cd %t.cfgtest
+// RUN: ln -sf %clang test123-clang
+// RUN: echo "-ferror-limit=666" > test123.cfg
+// RUN: cd $PWD
+// RUN: %t.cfgtest/test123-clang -v -c %s -o - 2>&1 | FileCheck %s
+
+// CHECK: Configuration file:{{.*}}test123.cfg
+// CHECK: -ferror-limit{{.*}}666
Index: test/Dr

[PATCH] D24933: Enable configuration files in clang

2016-10-04 Thread Serge Pavlov via cfe-commits
sepavloff added inline comments.


> mgorny wrote in driver.cpp:314
> Please document what this function does, exactly. I see you've documented it 
> in call site but a doc here would be helpful as well.

The function is documented now.

> mgorny wrote in driver.cpp:376
> Are you sure about the name? I would rather see `TARGET-clang.cfg` than a 
> name that doesn't explicitly mention that the file is for clang.

You are right. Changed the comment.

https://reviews.llvm.org/D24933



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


[PATCH] D23096: [Sema] Pass CombineWithOuterScope = true to constructor of LocalInstantiationScope

2016-10-05 Thread Serge Pavlov via cfe-commits
sepavloff added a comment.

IIUC, the problem is observed because `Sema::getTemplateInstantiationArgs` does 
not handle the case of variable templates properly. Classes and functions are 
declaration contexts and implementation of the aforementioned function (and 
probably others) relies on this fact. Variable does not represents a context, 
and this causes errors like this. We cannot make 
`VarTemplateSpecializationDecl` a subclass of `DeclContext` because the latter 
not only serves as a host for other declarations but also supports name lookup. 
None is pertinent to the case of variable specialization.

I think, logic of `getTemplateInstantiationArgs` should be changed. The new 
implementation could inspect current instantiation 
(`Sema::ActiveTemplateInstantiations`) to check if it is an instantiation of a 
variable template. This could eliminate need of `VarTemplateSpec` and 
`VarTemplateSpecializationRAII`. Such solution looks more flexible as variable 
initializer may contain references to other variable instantiations, so single 
value of `VarTemplateSpec` is not sufficient to track instantiations.


https://reviews.llvm.org/D23096



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


[PATCH] D21508: Make friend function template definition available if class is instantiated.

2016-10-11 Thread Serge Pavlov via cfe-commits
sepavloff updated this revision to Diff 74218.
sepavloff added a comment.

Updated comments, NFC otherwise.


https://reviews.llvm.org/D21508

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/friend2.cpp

Index: test/SemaCXX/friend2.cpp
===
--- test/SemaCXX/friend2.cpp
+++ test/SemaCXX/friend2.cpp
@@ -101,7 +101,6 @@
   friend void func_12(int x = 0);  // expected-error{{friend declaration specifying a default argument must be the only declaration}}
 };
 
-
 namespace pr22307 {
 
 struct t {
@@ -170,3 +169,70 @@
 template class Test;
 
 }
+
+// Case of template friend functions.
+
+template void func_21(T *x);
+template
+struct C21a {
+  template friend void func_21(T *x) {}
+};
+template
+struct C21b {
+  template friend void func_21(T *x) {}
+};
+
+
+template inline void func_22(T *x) {}
+template
+struct C22a {
+  template friend void func_22(T *x) {}
+};
+template
+struct C22b {
+  template friend void func_22(T *x) {}
+};
+
+
+template
+struct C23a {
+  template friend void func_23(T *x) {}
+};
+template
+struct C23b {
+  template friend void func_23(T *x) {}
+};
+
+
+template inline void func_24(T *x) {}  // expected-note{{previous definition is here}}
+template
+struct C24 {
+  template friend void func_24(T *x) {} // expected-error{{redefinition of 'func_24'}}
+};
+
+C24 v24;  // expected-note{{in instantiation of template class 'C24' requested here}}
+
+
+template inline void func_25(T *x);
+template
+struct C25a {
+  template friend void func_25(T *x) {} // expected-note{{previous definition is here}}
+};
+template
+struct C25b {
+  template friend void func_25(T *x) {} // expected-error{{redefinition of 'func_25'}}
+};
+
+C25a v25a;
+C25b v25b;  // expected-note{{in instantiation of template class 'C25b' requested here}}
+
+
+template void func_26(T *x);
+template
+struct C26 {
+  template friend void func_26(T *x) {}  // expected-error{{redefinition of 'func_26'}}
+ // expected-note@-1{{previous definition is here}}
+};
+
+C26 v26a;
+C26 v26b;  //expected-note{{in instantiation of template class 'C26' requested here}}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8846,10 +8846,23 @@
 
 if (FunctionTemplateDecl *OldTemplateDecl
   = dyn_cast(OldDecl)) {
-  NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());
   FunctionTemplateDecl *NewTemplateDecl
 = NewFD->getDescribedFunctionTemplate();
   assert(NewTemplateDecl && "Template/non-template mismatch");
+  Redeclaration = shouldLinkDependentDeclWithPrevious(NewTemplateDecl,
+  OldTemplateDecl);
+  if (Redeclaration &&
+  (NewTemplateDecl->getFriendObjectKind() != Decl::FOK_None ||
+   OldTemplateDecl->getFriendObjectKind() != Decl::FOK_None))
+if (FunctionTemplateDecl *NewDef = NewTemplateDecl->getDefinition())
+  if (FunctionTemplateDecl *OldDef = OldTemplateDecl->getDefinition()) {
+Diag(NewDef->getLocation(), diag::err_redefinition)
+<< NewDef->getDeclName();
+Diag(OldDef->getLocation(), diag::note_previous_definition);
+Redeclaration = false;
+  }
+  if (Redeclaration)
+NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());
   if (CXXMethodDecl *Method
 = dyn_cast(NewTemplateDecl->getTemplatedDecl())) {
 Method->setAccess(OldTemplateDecl->getAccess());
Index: lib/AST/DeclTemplate.cpp
===
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -289,6 +289,27 @@
   }
 }
 
+FunctionTemplateDecl *FunctionTemplateDecl::getDefinition() const {
+  for (auto *R : redecls()) {
+FunctionTemplateDecl *F = cast(R);
+if (F->isThisDeclarationADefinition())
+  return F;
+
+// If template does not have a body, probably it is instantiated from
+// another template and is not used yet.
+if (FunctionTemplateDecl *P = F->getInstantiatedFromMemberTemplate()) {
+  // If we have hit a point where the user provided a specialization of
+  // this template, we're done looking.
+  if (F->isMemberSpecialization())
+return F;
+  if (FunctionTemplateDecl *Def = P->getDefinition())
+return Def;
+}
+  }
+
+  return nullptr;
+}
+
 llvm::FoldingSetVector &
 FunctionTemplateDecl::getSpecializations() const {
   LoadLazySpecializations();
Index: include/clang/AST/DeclTemplate.h
===
--- include/clang/AST/DeclTemplate.h
+++ include/clang/AST/DeclTemplate.h
@@ -933,6 +933,15 @@
 return getTemplatedDecl()->isThisDeclarationADefinition();
   

r318896 - [DeclPrinter] Allow printing fully qualified name of function declaration

2017-11-22 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Wed Nov 22 21:38:20 2017
New Revision: 318896

URL: http://llvm.org/viewvc/llvm-project?rev=318896&view=rev
Log:
[DeclPrinter] Allow printing fully qualified name of function declaration

When requesting a tooltip for a function call in an IDE, the fully
qualified name helps to remove ambiguity in the function signature.

Patch by Nikolai Kosjar!

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

Modified:
cfe/trunk/include/clang/AST/PrettyPrinter.h
cfe/trunk/lib/AST/DeclPrinter.cpp
cfe/trunk/unittests/AST/DeclPrinterTest.cpp

Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=318896&r1=318895&r2=318896&view=diff
==
--- cfe/trunk/include/clang/AST/PrettyPrinter.h (original)
+++ cfe/trunk/include/clang/AST/PrettyPrinter.h Wed Nov 22 21:38:20 2017
@@ -51,7 +51,8 @@ struct PrintingPolicy {
   TerseOutput(false), PolishForDeclaration(false),
   Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
   IncludeNewlines(true), MSVCFormatting(false),
-  ConstantsAsWritten(false), SuppressImplicitBase(false) { }
+  ConstantsAsWritten(false), SuppressImplicitBase(false),
+  FullyQualifiedName(false) { }
 
   /// Adjust this printing policy for cases where it's known that we're
   /// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -220,6 +221,10 @@ struct PrintingPolicy {
 
   /// When true, don't print the implicit 'self' or 'this' expressions.
   bool SuppressImplicitBase : 1;
+
+  /// When true, print the fully qualified name of function declarations.
+  /// This is the opposite of SuppressScope and thus overrules it.
+  bool FullyQualifiedName : 1;
 };
 
 } // end namespace clang

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=318896&r1=318895&r2=318896&view=diff
==
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Wed Nov 22 21:38:20 2017
@@ -580,13 +580,19 @@ void DeclPrinter::VisitFunctionDecl(Func
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
   std::string Proto;
-  if (!Policy.SuppressScope) {
-if (const NestedNameSpecifier *NS = D->getQualifier()) {
-  llvm::raw_string_ostream OS(Proto);
-  NS->print(OS, Policy);
+
+  if (Policy.FullyQualifiedName) {
+Proto += D->getQualifiedNameAsString();
+  } else {
+if (!Policy.SuppressScope) {
+  if (const NestedNameSpecifier *NS = D->getQualifier()) {
+llvm::raw_string_ostream OS(Proto);
+NS->print(OS, Policy);
+  }
 }
+Proto += D->getNameInfo().getAsString();
   }
-  Proto += D->getNameInfo().getAsString();
+
   if (GuideDecl)
 Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
   if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {

Modified: cfe/trunk/unittests/AST/DeclPrinterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/DeclPrinterTest.cpp?rev=318896&r1=318895&r2=318896&view=diff
==
--- cfe/trunk/unittests/AST/DeclPrinterTest.cpp (original)
+++ cfe/trunk/unittests/AST/DeclPrinterTest.cpp Wed Nov 22 21:38:20 2017
@@ -104,15 +104,17 @@ PrintedDeclMatches(StringRef Code, const
   return ::testing::AssertionSuccess();
 }
 
-::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
-   StringRef DeclName,
-   StringRef ExpectedPrinted) {
+::testing::AssertionResult
+PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,
+StringRef ExpectedPrinted,
+PrintingPolicyModifier PolicyModifier = nullptr) {
   std::vector Args(1, "-std=c++98");
   return PrintedDeclMatches(Code,
 Args,
 namedDecl(hasName(DeclName)).bind("id"),
 ExpectedPrinted,
-"input.cc");
+"input.cc",
+PolicyModifier);
 }
 
 ::testing::AssertionResult
@@ -350,6 +352,47 @@ TEST(DeclPrinter, TestFunctionDecl1) {
 "void A()"));
 }
 
+TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) {
+ASSERT_TRUE(PrintedDeclCXX98Matches(
+  "void A();",
+  "A",
+  "void A()",
+  [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
+}
+
+TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) {
+ASSERT_TRUE(PrintedDeclCXX98Matches(
+  "namespace X { void A(); };",
+  "A",
+  "void X::A()",
+  [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }))

r319178 - Refactor functions PrintTemplateArgumentList

2017-11-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Tue Nov 28 08:14:14 2017
New Revision: 319178

URL: http://llvm.org/viewvc/llvm-project?rev=319178&view=rev
Log:
Refactor functions PrintTemplateArgumentList

These functions were defined as static members of TemplateSpecializationType.
Now they are moved to namespace level. Previously there were different
implementations for lists containing TemplateArgument and TemplateArgumentLoc,
now these implementations share the same code.

This change is a result of refactoring patch D40508. NFC.

Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/AST/NestedNameSpecifier.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=319178&r1=319177&r2=319178&view=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Nov 28 08:14:14 2017
@@ -4533,21 +4533,6 @@ public:
   static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
 bool &InstantiationDependent);
 
-  /// \brief Print a template argument list, including the '<' and '>'
-  /// enclosing the template arguments.
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-ArrayRef Args,
-const PrintingPolicy &Policy,
-bool SkipBrackets = false);
-
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-ArrayRef Args,
-const PrintingPolicy &Policy);
-
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-const TemplateArgumentListInfo &,
-const PrintingPolicy &Policy);
-
   /// True if this template specialization type matches a current
   /// instantiation in the context in which it is found.
   bool isCurrentInstantiation() const {
@@ -4623,6 +4608,20 @@ public:
   }
 };
 
+/// \brief Print a template argument list, including the '<' and '>'
+/// enclosing the template arguments.
+void printTemplateArgumentList(raw_ostream &OS,
+   ArrayRef Args,
+   const PrintingPolicy &Policy);
+
+void printTemplateArgumentList(raw_ostream &OS,
+   ArrayRef Args,
+   const PrintingPolicy &Policy);
+
+void printTemplateArgumentList(raw_ostream &OS,
+   const TemplateArgumentListInfo &Args,
+   const PrintingPolicy &Policy);
+
 /// The injected class name of a C++ class template or class
 /// template partial specialization.  Used to record that a type was
 /// spelled with a bare identifier rather than as a template-id; the

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=319178&r1=319177&r2=319178&view=diff
==
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Nov 28 08:14:14 2017
@@ -6274,9 +6274,8 @@ void ASTContext::getObjCEncodingForTypeI
   = dyn_cast(RDecl)) {
 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
 llvm::raw_string_ostream OS(S);
-TemplateSpecializationType::PrintTemplateArgumentList(OS,
-TemplateArgs.asArray(),
-(*this).getPrintingPolicy());
+printTemplateArgumentList(OS, TemplateArgs.asArray(),
+  getPrintingPolicy());
   }
 } else {
   S += '?';

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=319178&r1=319177&r2=319178&view=diff
==
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Nov 28 08:14:14 2017
@@ -1506,8 +1506,7 @@ void NamedDecl::printQualifiedName(raw_o
 if (const auto *Spec = dyn_cast(DC)) {
   OS << Spec->getName();
   const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-  TemplateSpecializationType::PrintTemplateArgumentList(
-  OS, TemplateArgs.asArray(), P);
+  printTemplateArgumentList(OS, TemplateArgs.asArray(), P);
 } else if (const auto *ND = dyn_cast(DC)) {
   if (P.SuppressUnwrittenScope &&

r319290 - Use static function instead of anonymous namespace

2017-11-28 Thread Serge Pavlov via cfe-commits
Author: sepavloff
Date: Tue Nov 28 21:10:11 2017
New Revision: 319290

URL: http://llvm.org/viewvc/llvm-project?rev=319290&view=rev
Log:
Use static function instead of anonymous namespace

Modified:
cfe/trunk/lib/AST/TypePrinter.cpp

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=319290&r1=319289&r2=319290&view=diff
==
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Tue Nov 28 21:10:11 2017
@@ -1529,10 +1529,9 @@ static const TemplateArgument &getArgume
   return A.getArgument();
 }
 
-namespace {
 template
-void printTo(raw_ostream &OS, ArrayRef Args, const PrintingPolicy &Policy,
- bool SkipBrackets) {
+static void printTo(raw_ostream &OS, ArrayRef Args,
+const PrintingPolicy &Policy, bool SkipBrackets) {
   const char *Comma = Policy.MSVCFormatting ? "," : ", ";
   if (!SkipBrackets)
 OS << '<';
@@ -1576,7 +1575,6 @@ void printTo(raw_ostream &OS, ArrayRef';
 }
-}
 
 void clang::printTemplateArgumentList(raw_ostream &OS,
   const TemplateArgumentListInfo &Args,


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


[clang] 9424497 - [Clang] Use virtual FS in processing config files

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T16:28:51+07:00
New Revision: 9424497e43aff088e014d65fd952ec557e28e6cf

URL: 
https://github.com/llvm/llvm-project/commit/9424497e43aff088e014d65fd952ec557e28e6cf
DIFF: 
https://github.com/llvm/llvm-project/commit/9424497e43aff088e014d65fd952ec557e28e6cf.diff

LOG: [Clang] Use virtual FS in processing config files

Clang has support of virtual file system for the purpose of testing, but
treatment of config files did not use it. This change enables VFS in it
as well.

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

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 155eababa81e6..4804856bc8f5c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,8 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
+- Clang configuration files are now read through the virtual file system
+  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ca8e0e5240e1d..217236f459a50 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,7 +911,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
&C,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl &FilePath,
-  ArrayRef Dirs, StringRef FileName) {
+  ArrayRef Dirs, StringRef FileName,
+  llvm::vfs::FileSystem &FS) {
   SmallString<128> WPath;
   for (const StringRef &Dir : Dirs) {
 if (Dir.empty())
@@ -919,7 +920,8 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-if (llvm::sys::fs::is_regular_file(WPath)) {
+auto Status = FS.status(WPath);
+if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
   FilePath = std::move(WPath);
   return true;
 }
@@ -930,7 +932,7 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -970,7 +972,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -979,7 +981,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1004,13 +1006,16 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath;
-if (llvm::sys::path::is_relative(CfgFileName))
-  llvm::sys::fs::current_path(CfgFilePath);
-llvm::sys::path::append(CfgFilePath, CfgFileName);
-if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
-  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-  return true;
+SmallString<128> CfgFilePath(CfgFileName);
+if (llvm::sys::path::is_relative(CfgFilePath)) {
+  if (getVFS().makeAbsolute(CfgFilePath))
+return true;
+  auto Status = getVFS().status(CfgFilePath);
+  if (!Status ||
+  Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+return true;
+  }
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1069,17 +1074,19 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architecture.
   llvm::SmallString<128> CfgFilePath;
   

[clang] 55e1441 - Revert "[Clang] Use virtual FS in processing config files"

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T16:43:15+07:00
New Revision: 55e1441f7b5d01a37fc46eb1711f03ee69845316

URL: 
https://github.com/llvm/llvm-project/commit/55e1441f7b5d01a37fc46eb1711f03ee69845316
DIFF: 
https://github.com/llvm/llvm-project/commit/55e1441f7b5d01a37fc46eb1711f03ee69845316.diff

LOG: Revert "[Clang] Use virtual FS in processing config files"

This reverts commit 9424497e43aff088e014d65fd952ec557e28e6cf.
Some buildbots failed, reverted for investigation.

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4804856bc8f5c..155eababa81e6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,8 +93,6 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
-- Clang configuration files are now read through the virtual file system
-  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 217236f459a50..ca8e0e5240e1d 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,8 +911,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
&C,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl &FilePath,
-  ArrayRef Dirs, StringRef FileName,
-  llvm::vfs::FileSystem &FS) {
+  ArrayRef Dirs, StringRef FileName) {
   SmallString<128> WPath;
   for (const StringRef &Dir : Dirs) {
 if (Dir.empty())
@@ -920,8 +919,7 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-auto Status = FS.status(WPath);
-if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
+if (llvm::sys::fs::is_regular_file(WPath)) {
   FilePath = std::move(WPath);
   return true;
 }
@@ -932,7 +930,7 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -972,7 +970,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -981,7 +979,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1006,16 +1004,13 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath(CfgFileName);
-if (llvm::sys::path::is_relative(CfgFilePath)) {
-  if (getVFS().makeAbsolute(CfgFilePath))
-return true;
-  auto Status = getVFS().status(CfgFilePath);
-  if (!Status ||
-  Status->getType() != llvm::sys::fs::file_type::regular_file) {
-Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-return true;
-  }
+SmallString<128> CfgFilePath;
+if (llvm::sys::path::is_relative(CfgFileName))
+  llvm::sys::fs::current_path(CfgFilePath);
+llvm::sys::path::append(CfgFilePath, CfgFileName);
+if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
+  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+  return true;
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1074,19 +1069,17 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architecture.
   llvm::SmallString<128> CfgFilePath;
   if (!FixedConfigFile.empty()) {
-if (searchForFile(CfgFilePath, CfgFileSearchDirs, Fi

[clang] 7b9fae0 - [Clang] Use virtual FS in processing config files

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T18:24:45+07:00
New Revision: 7b9fae05b4d0d3184ffc340e90d06a75e3cba2de

URL: 
https://github.com/llvm/llvm-project/commit/7b9fae05b4d0d3184ffc340e90d06a75e3cba2de
DIFF: 
https://github.com/llvm/llvm-project/commit/7b9fae05b4d0d3184ffc340e90d06a75e3cba2de.diff

LOG: [Clang] Use virtual FS in processing config files

Clang has support of virtual file system for the purpose of testing, but
treatment of config files did not use it. This change enables VFS in it
as well.

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

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 155eababa81e6..4804856bc8f5c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,8 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
+- Clang configuration files are now read through the virtual file system
+  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ca8e0e5240e1d..217236f459a50 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,7 +911,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
&C,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl &FilePath,
-  ArrayRef Dirs, StringRef FileName) {
+  ArrayRef Dirs, StringRef FileName,
+  llvm::vfs::FileSystem &FS) {
   SmallString<128> WPath;
   for (const StringRef &Dir : Dirs) {
 if (Dir.empty())
@@ -919,7 +920,8 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-if (llvm::sys::fs::is_regular_file(WPath)) {
+auto Status = FS.status(WPath);
+if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
   FilePath = std::move(WPath);
   return true;
 }
@@ -930,7 +932,7 @@ static bool searchForFile(SmallVectorImpl &FilePath,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -970,7 +972,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -979,7 +981,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1004,13 +1006,16 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath;
-if (llvm::sys::path::is_relative(CfgFileName))
-  llvm::sys::fs::current_path(CfgFilePath);
-llvm::sys::path::append(CfgFilePath, CfgFileName);
-if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
-  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-  return true;
+SmallString<128> CfgFilePath(CfgFileName);
+if (llvm::sys::path::is_relative(CfgFilePath)) {
+  if (getVFS().makeAbsolute(CfgFilePath))
+return true;
+  auto Status = getVFS().status(CfgFilePath);
+  if (!Status ||
+  Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+return true;
+  }
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1069,17 +1074,19 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architect

[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-09 Thread Serge Pavlov via cfe-commits

spavloff wrote:

`pragma pack` uses pragma stack and it is allowed in any place: 
https://godbolt.org/z/f8fP1vn63 . If such pragma presents in the late-parsed 
template, and push-pop operations in it are not balanced, the late parse of 
such function can break the pragma stack and next templates can be parsed 
incorrectly. It is not a FP pragma, but it demonstrates that the compiler must 
provide some Sema state isolation for late parsed templates.

For floating-point pragmas the stack could be cleared once, before the late 
parsing takes place. However it is complicated by the fact that the pragma 
stack set in precompiled header must be available in the unit that uses the 
header. Another complication is implicit assumption in some places that the 
default FP options are defined by LangOpts. It is not true, in some cases 
target may modify the default state (i386 is an example).

This fix is not optimal. The problems mentioned above are solvable and they 
should be fixed. However to have a quick solution for the initial PR the fix 
probably could be used.


https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/70646

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/2] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema &S)
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From 44b096810d88da1d1331be12802c68cdf8e1785b Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/2] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e8892d1a550453..1d61dc7ff0aa26d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema &S)
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/70646

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/3] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema &S)
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From 44b096810d88da1d1331be12802c68cdf8e1785b Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/3] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e8892d1a550453..1d61dc7ff0aa26d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema &S)
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

>From 244e967fb48c0b3b75682a6a32c1afd148c8c203 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:12:49 +0700
Subject: [PATCH 3/3] Fix clang-format errors

---
 clang/include/clang/Sema/Sema.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1d61dc7ff0aa26d..d88c20e5170a661 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,7 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema &S)
-  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {
   S.FpPragmaStack.Stack.clear();
 }
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/70646

>From e1623db8f86a8584d17729f000a455f5672adad4 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/3] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..f146a162c1b8644 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema &S)
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From f6af73145fdf37a08a493a1a16775bbc60090fe0 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/3] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f146a162c1b8644..995d6ea1f9e8810 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema &S)
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

>From 517ee9663646e0ee4f12be4d2b5f24e91a8f0e83 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:12:49 +0700
Subject: [PATCH 3/3] Fix clang-format errors

---
 clang/include/clang/Sema/Sema.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 995d6ea1f9e8810..38377f01a10086f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,7 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema &S)
-  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {
   S.FpPragmaStack.Stack.clear();
 }
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits


@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema &S)
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}

spavloff wrote:

Added explicit stack reset.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 93ae263 - [clang] Run test on x86 only

2023-11-13 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-11-13T19:20:34+07:00
New Revision: 93ae26331592f41bf2b1d10b048743d80c468385

URL: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385
DIFF: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385.diff

LOG: [clang] Run test on x86 only

The test Sema/PR69717.cpp fails on platforms that do not support
pragma float_control. So run this test on x86 only.

Added: 


Modified: 
clang/test/Sema/PR69717.cpp

Removed: 




diff  --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
index 3207092b948ae86..42a87bd1ac1ec8d 100644
--- a/clang/test/Sema/PR69717.cpp
+++ b/clang/test/Sema/PR69717.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
+// REQUIRES: x86-registered-target
 // expected-no-diagnostics
 
 // Testcase for https://github.com/llvm/llvm-project/issues/69717



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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Added commit: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385
 to run the test on x86 only.


https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] fix test PR69717.cpp (PR #72134)

2023-11-13 Thread Serge Pavlov via cfe-commits

spavloff wrote:

@antmox Thank you for fixing that!
LGTM.
Could you please commit the patch when tests pass?

https://github.com/llvm/llvm-project/pull/72134
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/70646

When instantiation function, a call to Sema::resetFPOption was used to set the 
FP options associated with AST node. However this function also cleared FP 
pragma stack, and it is incorrect. Template instantiation takes place on AST 
representation and semantic information like the FP pragma stack should not 
affect it. This was a reason for miscompilation in some cases.

To make the Sema interface more consistent, now `resetFPOptions` does not clear 
FP pragma stack anymore. It is cleared in `FpPragmaStackSaveRAII`, which is 
used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717 
(Problems with float_control pragma stack in Clang 17.x).

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema &S)
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

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


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Ping.

https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> To be clear, we're still ensuring the current pragma state during 
> instantiation is what it was when the template is parsed, we're just not 
> incorrectly dropping all of the saved pragma state when we're doing it?

Yes, the pragma is used at parse stage to set correct FP options is AST nodes. 
During template instantiation the function `resetFPOptions` is used to set the 
required FP options in Sema, because in some cases (ImplicitCast) the options 
are taken from Sema and not AST node. As a result the new AST nodes get FP 
otions as they are specified in the template pattern.

The issue with `resetFPOptions` was that it also reset pragma stack. It is OK 
for late template parse, or for the functions that are instantiated at the end 
of translation unit, but not for templates that are instantiated immediately, 
like consexpr functions.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Actually the pragma stack is not saved during template instantiation. It is 
saved during late template parsing using class `FpPragmaStackSaveRAII`. For 
template instantiation the dependency on the stack can be considered as an 
error, because all information about FP options should be taken from AST.

That was the reason for this issue - the pragma stack was cleared because 
`resetFPOptions` was introduced for late parsing. If instantiation was made 
during parsing, it spoiled the pragma stack.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-31 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Late parsing (in contrast to template instantiation) is sensitive to the pragma 
stack because the late parsed text may contain pragmas. If, for example, the 
parsed text contains unbalanced pus/pop pragmas, it is detected if the pragma 
stack is empty, but can be missed if there is an unfinished pragma.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-31 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Thanks!

https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-31 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff edited 
https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff commented:

The patch looks good but I am not familiar with PPC instructions enough. Could 
you please run the runtime tests from here: 
https://github.com/llvm/llvm-test-suite/tree/main/MultiSource/UnitTests/Float/rounding?
 You just need to build application from two files: `clang rounding.c 
rounding-dynamic.c`.

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits


@@ -8900,6 +8900,83 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
   return FP;
 }
 
+SDValue PPCTargetLowering::LowerSET_ROUNDING(SDValue Op,
+ SelectionDAG &DAG) const {
+  SDLoc Dl(Op);
+  MachineFunction &MF = DAG.getMachineFunction();
+  EVT PtrVT = getPointerTy(MF.getDataLayout());
+  SDValue Chain = Op.getOperand(0);
+
+  // If requested mode is constant, just use simpler mtfsb.
+  if (auto *CVal = dyn_cast(Op.getOperand(1))) {
+uint64_t Mode = CVal->getZExtValue();
+if (Mode >= 4)
+  llvm_unreachable("Unsupported rounding mode!");

spavloff wrote:

Would using `assert` be more appropriate?

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits


@@ -8900,6 +8900,83 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
   return FP;
 }
 
+SDValue PPCTargetLowering::LowerSET_ROUNDING(SDValue Op,
+ SelectionDAG &DAG) const {
+  SDLoc Dl(Op);
+  MachineFunction &MF = DAG.getMachineFunction();
+  EVT PtrVT = getPointerTy(MF.getDataLayout());
+  SDValue Chain = Op.getOperand(0);
+
+  // If requested mode is constant, just use simpler mtfsb.
+  if (auto *CVal = dyn_cast(Op.getOperand(1))) {
+uint64_t Mode = CVal->getZExtValue();
+if (Mode >= 4)
+  llvm_unreachable("Unsupported rounding mode!");
+unsigned InternalRnd = Mode ^ (~(Mode >> 1) & 1);
+SDNode *SetHi = DAG.getMachineNode(
+(InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
+{DAG.getConstant(30, Dl, MVT::i32, true), Chain});
+SDNode *SetLo = DAG.getMachineNode(
+(InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
+{DAG.getConstant(31, Dl, MVT::i32, true), SDValue(SetHi, 0)});
+return SDValue(SetLo, 0);
+  }
+
+  // Use x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Power format.
+  SDValue One = DAG.getConstant(1, Dl, MVT::i32);
+  SDValue SrcFlag = DAG.getNode(ISD::AND, Dl, MVT::i32, Op.getOperand(1),
+DAG.getConstant(3, Dl, MVT::i32));
+  SDValue DstFlag = DAG.getNode(
+  ISD::XOR, Dl, MVT::i32, SrcFlag,
+  DAG.getNode(ISD::AND, Dl, MVT::i32,
+  DAG.getNOT(Dl,
+ DAG.getNode(ISD::SRL, Dl, MVT::i32, SrcFlag, One),
+ MVT::i32),
+  One));
+  SDValue MFFS = DAG.getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
+  Chain = MFFS.getValue(1);
+  SDValue NewFPSCR;
+  if (isTypeLegal(MVT::i64)) {
+// Set the last two bits (rounding mode) of bitcasted FPSCR.
+NewFPSCR = DAG.getNode(
+ISD::OR, Dl, MVT::i64,
+DAG.getNode(ISD::AND, Dl, MVT::i64,
+DAG.getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
+DAG.getNOT(Dl, DAG.getConstant(3, Dl, MVT::i64), 
MVT::i64)),
+DAG.getNode(ISD::ZERO_EXTEND, Dl, MVT::i64, DstFlag));

spavloff wrote:

Is there guarantee that the upper bits (63-2) of `DestFlag` are zeros? 

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff edited 
https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-28 Thread Serge Pavlov via cfe-commits

spavloff wrote:

LGTM.

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-29 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/73770

Increment and decrement are equivalent to adding or subtracting 1. For the 
floating-point values these operations depend on the current rounding mode. 
Teach constant evaluator to perform ++ and -- according to the current 
floating-point environment.

>From 48ed25acfa5765af607efce2309605b96a09d477 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 29 Nov 2023 00:53:54 +0700
Subject: [PATCH] [clang] Use current rounding mode for float inc/dec

Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.
---
 clang/lib/AST/ExprConstant.cpp   |  6 --
 clang/test/SemaCXX/rounding-math.cpp | 21 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue &Subobj, QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

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


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/73770

>From 48ed25acfa5765af607efce2309605b96a09d477 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 29 Nov 2023 00:53:54 +0700
Subject: [PATCH 1/2] [clang] Use current rounding mode for float inc/dec

Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.
---
 clang/lib/AST/ExprConstant.cpp   |  6 --
 clang/test/SemaCXX/rounding-math.cpp | 21 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue &Subobj, QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

>From 6b558d3737366891ba1afeec91f7d9796b9e8b42 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 30 Nov 2023 13:25:38 +0700
Subject: [PATCH 2/2] Use getActiveRoundingMode

---
 clang/lib/AST/ExprConstant.cpp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e0abe832c47a9f1..2aafe5bd5289fc2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,13 +4623,13 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
-llvm::RoundingMode RM =
-E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
+llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
+APFloat::opStatus St;
 if (AccessKind == AK_Increment)
-  Value.add(One, RM);
+  St = Value.add(One, RM);
 else
-  Value.subtract(One, RM);
-return true;
+  St = Value.subtract(One, RM);
+return checkFloatingPointResult(Info, E, St);
   }
   bool foundPointer(APValue &Subobj, QualType SubobjType) {
 if (!checkConst(SubobjType))

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


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits


@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();

spavloff wrote:

Yes, it should. Thank you!

https://github.com/llvm/llvm-project/pull/73770
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/73770
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b822efc - [FPEnv] Allow CompoundStmt to keep FP options

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T14:32:33+07:00
New Revision: b822efc7404bf09ccfdc1ab7657475026966c3b2

URL: 
https://github.com/llvm/llvm-project/commit/b822efc7404bf09ccfdc1ab7657475026966c3b2
DIFF: 
https://github.com/llvm/llvm-project/commit/b822efc7404bf09ccfdc1ab7657475026966c3b2.diff

LOG: [FPEnv] Allow CompoundStmt to keep FP options

AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.

This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.

To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.

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

Added: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c

Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 




diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index 5638df42a1c50..ed49e0007a189 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,6 +160,7 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
+  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
@@ -317,6 +318,7 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument &TA);
   void VisitTypeTemplateArgument(const TemplateArgument &TA);

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 653ce4b4b90c5..49a66a1ea5b86 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,6 +19,7 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -128,6 +129,10 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
+/// True if the compound statement has one or more pragmas that set some
+/// floating-point features.
+unsigned HasFPFeatures : 1;
+
 unsigned NumStmts;
   };
 
@@ -1398,8 +1403,9 @@ class NullStmt : public Stmt {
 };
 
 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class C

[clang] 0401fd1 - Fix warning on unhandled enumeration value

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T15:17:29+07:00
New Revision: 0401fd12d4aa0553347fe34d666fb236d8719173

URL: 
https://github.com/llvm/llvm-project/commit/0401fd12d4aa0553347fe34d666fb236d8719173
DIFF: 
https://github.com/llvm/llvm-project/commit/0401fd12d4aa0553347fe34d666fb236d8719173.diff

LOG: Fix warning on unhandled enumeration value

Added: 


Modified: 
clang/lib/AST/StmtPrinter.cpp

Removed: 




diff  --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index f2aa8fb2659d..983fd39874f0 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -198,6 +198,8 @@ void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
   Indent() << "#pragma clang fp exceptions(";
   switch (FPO.getSpecifiedExceptionModeOverride()) {
+  default:
+break;
   case LangOptions::FPE_Ignore:
 OS << "ignore";
 break;



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


[clang] dc34d8d - Revert "[FPEnv] Allow CompoundStmt to keep FP options"

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T15:42:39+07:00
New Revision: dc34d8df4c48b3a8f474360970cae8a58e6c84f0

URL: 
https://github.com/llvm/llvm-project/commit/dc34d8df4c48b3a8f474360970cae8a58e6c84f0
DIFF: 
https://github.com/llvm/llvm-project/commit/dc34d8df4c48b3a8f474360970cae8a58e6c84f0.diff

LOG: Revert "[FPEnv] Allow CompoundStmt to keep FP options"

On some buildbots test `ast-print-fp-pragmas.c` fails, need to investigate it.

This reverts commit 0401fd12d4aa0553347fe34d666fb236d8719173.
This reverts commit b822efc7404bf09ccfdc1ab7657475026966c3b2.

Added: 


Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c



diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index ed49e0007a189..5638df42a1c50 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,7 +160,6 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
-  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
@@ -318,7 +317,6 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
-  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument &TA);
   void VisitTypeTemplateArgument(const TemplateArgument &TA);

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 49a66a1ea5b86..653ce4b4b90c5 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,7 +19,6 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -129,10 +128,6 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
-/// True if the compound statement has one or more pragmas that set some
-/// floating-point features.
-unsigned HasFPFeatures : 1;
-
 unsigned NumStmts;
   };
 
@@ -1403,9 +1398,8 @@ class NullStmt : public Stmt {
 };
 
 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class CompoundStmt final
-: public Stmt,
-  private llvm::TrailingObjects {
+class CompoundStmt final : public Stmt,
+   private llvm::TrailingObjects 
{
   friend class ASTStmtReader;
   friend TrailingObjects;
 
@@ -1415,49 +1409,27 @@ class CompoundStmt final
   /// The location of the closing "}".
   SourceLocation RBraceLoc;
 
-  CompoundStmt(ArrayRef Stmts, FPOptionsOverride FPFeatures,
-   SourceLocation LB, SourceLocation RB);
+  CompoundStmt(ArrayRef Stmts, SourceLocation LB, SourceLocation RB);
   explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
 
   void setStmts(ArrayRef Stmts);
 
-  /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
-  void setStoredFPFeatures(FPOptionsOverride F) {
-assert(hasStoredFPFeatures());
-*getTrailingObjects() = F;
-  }
-
-  size_t numTrailingObjects(OverloadToken) const {
-return CompoundStmtBits.NumStmts;
-  }
-
 public:
   static CompoundStmt *Create(const ASTContext &C, ArrayRef Stmts,
-  FPOptionsOverride FPFeatures, SourceLocation LB,
-  SourceLocation RB);
+  SourceLocation LB, SourceLocation RB);
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
   : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
 CompoundStmtBits.NumStmts = 0;
-CompoundStmtBits.Has

[clang] f7819ce - [FPEnv] Allow CompoundStmt to keep FP options

2022-07-03 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-03T17:06:26+07:00
New Revision: f7819ce166bcc472108cf7c05f86edcf4ee9e6cf

URL: 
https://github.com/llvm/llvm-project/commit/f7819ce166bcc472108cf7c05f86edcf4ee9e6cf
DIFF: 
https://github.com/llvm/llvm-project/commit/f7819ce166bcc472108cf7c05f86edcf4ee9e6cf.diff

LOG: [FPEnv] Allow CompoundStmt to keep FP options

This is a recommit of b822efc7404bf09ccfdc1ab7657475026966c3b2,
reverted in dc34d8df4c48b3a8f474360970cae8a58e6c84f0. The commit caused
fails because the test ast-print-fp-pragmas.c did not specify particular
target, and it failed on targets which do not support constrained
intrinsics. The original commit message is below.

AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.

This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.

To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.

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

Added: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c

Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 




diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index 5638df42a1c5..ed49e0007a18 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,6 +160,7 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
+  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
@@ -317,6 +318,7 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument &TA);
   void VisitTypeTemplateArgument(const TemplateArgument &TA);

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 653ce4b4b90c..49a66a1ea5b8 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,6 +19,7 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -128,6 +129,10 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
+ 

[clang] 2bb7c54 - [Clang] Remove unused parameter. NFC

2022-08-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-08-01T14:53:13+07:00
New Revision: 2bb7c54621f31a957302a4deb3d25b752acb07bd

URL: 
https://github.com/llvm/llvm-project/commit/2bb7c54621f31a957302a4deb3d25b752acb07bd
DIFF: 
https://github.com/llvm/llvm-project/commit/2bb7c54621f31a957302a4deb3d25b752acb07bd.diff

LOG: [Clang] Remove unused parameter. NFC

BinaryOperator::getFPFeatures get parameter, which is not used. Similar
methods of other AST nodes do not have any parameter.

Added: 


Modified: 
clang/include/clang/AST/Expr.h
clang/lib/AST/ASTImporter.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/TreeTransform.h

Removed: 




diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 1f3d524691ed6..1fc6dc90b6c7c 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4009,7 +4009,7 @@ class BinaryOperator : public Expr {
   }
 
   // This is used in ASTImporter
-  FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+  FPOptionsOverride getFPFeatures() const {
 if (BinaryOperatorBits.HasFPFeatures)
   return getStoredFPFeatures();
 return FPOptionsOverride();

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 0273e50683716..159010713f434 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7224,7 +7224,7 @@ ExpectedStmt 
ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
   return BinaryOperator::Create(
   Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
   E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
-  E->getFPFeatures(Importer.getFromContext().getLangOpts()));
+  E->getFPFeatures());
 }
 
 ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) 
{
@@ -7335,7 +7335,7 @@ 
ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
   return CompoundAssignOperator::Create(
   Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
   E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
-  E->getFPFeatures(Importer.getFromContext().getLangOpts()),
+  E->getFPFeatures(),
   ToComputationLHSType, ToComputationResultType);
 }
 

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ee3f9c6767fa9..30c1f5c978945 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7381,7 +7381,7 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
   return BinaryOperator::Create(Context, BO->getLHS(), RHS.get(), BO_Comma,
 BO->getType(), BO->getValueKind(),
 BO->getObjectKind(), BO->getOperatorLoc(),
-BO->getFPFeatures(getLangOpts()));
+BO->getFPFeatures());
 }
   }
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c52e12d3eb9ba..86d92158da8df 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11186,7 +11186,7 @@ 
TreeTransform::TransformBinaryOperator(BinaryOperator *E) {
 return getDerived().RebuildBinaryOperator(
 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
   Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
-  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
+  FPOptionsOverride NewOverrides(E->getFPFeatures());
   getSema().CurFPFeatures =
   NewOverrides.applyOverrides(getSema().getLangOpts());
   getSema().FpPragmaStack.CurrentValue = NewOverrides;
@@ -11253,7 +11253,7 @@ ExprResult
 TreeTransform::TransformCompoundAssignOperator(
   CompoundAssignOperator 
*E) {
   Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
-  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
+  FPOptionsOverride NewOverrides(E->getFPFeatures());
   getSema().CurFPFeatures =
   NewOverrides.applyOverrides(getSema().getLangOpts());
   getSema().FpPragmaStack.CurrentValue = NewOverrides;



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


[clang] 5537b22 - Make CompoundStmtBitfields::NumStmts not a bit-field

2022-05-20 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-05-20T14:20:09+07:00
New Revision: 5537b22ccbdc562929949844f9f816cf720e5205

URL: 
https://github.com/llvm/llvm-project/commit/5537b22ccbdc562929949844f9f816cf720e5205
DIFF: 
https://github.com/llvm/llvm-project/commit/5537b22ccbdc562929949844f9f816cf720e5205.diff

LOG: Make CompoundStmtBitfields::NumStmts not a bit-field

Number of statements in CompoundStmt is kept in a bit-field of the common
part of Stmt. The field has 24 bits for the number. To allocate a new
bit field (as attempted in https://reviews.llvm.org/D123952), this
number must be reduced, maximal number of statements in a compound
statement becomes smaller. It can result in compilation errors of some
programs.

With this change the number of statements is kept in a field of type
'unsigned int' rather than in bit-field. To make room in CompoundStmtBitfields
LBraceLoc is moved to fields of CompoundStmt.

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

Added: 


Modified: 
clang/include/clang/AST/Stmt.h
clang/lib/AST/Stmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 1135981319c1a..653ce4b4b90c5 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -128,10 +128,7 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
-unsigned NumStmts : 32 - NumStmtBits;
-
-/// The location of the opening "{".
-SourceLocation LBraceLoc;
+unsigned NumStmts;
   };
 
   class LabelStmtBitfields {
@@ -1406,7 +1403,10 @@ class CompoundStmt final : public Stmt,
   friend class ASTStmtReader;
   friend TrailingObjects;
 
-  /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
+  /// The location of the opening "{".
+  SourceLocation LBraceLoc;
+
+  /// The location of the closing "}".
   SourceLocation RBraceLoc;
 
   CompoundStmt(ArrayRef Stmts, SourceLocation LB, SourceLocation RB);
@@ -1420,9 +1420,8 @@ class CompoundStmt final : public Stmt,
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
-  : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
+  : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
 CompoundStmtBits.NumStmts = 0;
-CompoundStmtBits.LBraceLoc = Loc;
   }
 
   // Build an empty compound statement.
@@ -1505,10 +1504,10 @@ class CompoundStmt final : public Stmt,
 return const_cast(this)->getStmtExprResult();
   }
 
-  SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
+  SourceLocation getBeginLoc() const { return LBraceLoc; }
   SourceLocation getEndLoc() const { return RBraceLoc; }
 
-  SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
+  SourceLocation getLBracLoc() const { return LBraceLoc; }
   SourceLocation getRBracLoc() const { return RBraceLoc; }
 
   static bool classof(const Stmt *T) {

diff  --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index be19d3b2cce2c..d562717bf6b22 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -363,10 +363,9 @@ int64_t Stmt::getID(const ASTContext &Context) const {
 
 CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB,
SourceLocation RB)
-: Stmt(CompoundStmtClass), RBraceLoc(RB) {
+: Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
   CompoundStmtBits.NumStmts = Stmts.size();
   setStmts(Stmts);
-  CompoundStmtBits.LBraceLoc = LB;
 }
 
 void CompoundStmt::setStmts(ArrayRef Stmts) {

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index 77ea1b95d5be5..09342de1eee96 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -155,7 +155,7 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   while (NumStmts--)
 Stmts.push_back(Record.readSubStmt());
   S->setStmts(Stmts);
-  S->CompoundStmtBits.LBraceLoc = readSourceLocation();
+  S->LBraceLoc = readSourceLocation();
   S->RBraceLoc = readSourceLocation();
 }
 



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


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-17 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/85605

Attribute `optnone` must turn off all optimizations including fast-math ones. 
Actually AST nodes in the 'optnone' function still had fast-math flags. This 
change implements fixing FP options before function body is parsed.

>From 24c96a1f43b8d2e0977331c92aec1c14ccc504a2 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH] [clang] Set correct FPOptions if attribute 'optnone' presents

Attribute `optnone` must turn off all optimizations including fast-math
ones. Actually AST nodes in the 'optnone' function still had fast-math
flags. This change implements fixing FP options before function body is
parsed.
---
 clang/include/clang/Basic/LangOptions.h | 11 +++
 clang/include/clang/Sema/Sema.h |  1 +
 clang/lib/Parse/ParseStmt.cpp   |  4 
 clang/lib/Sema/SemaDecl.cpp | 10 ++
 clang/test/AST/ast-dump-fpfeatures.cpp  | 11 +++
 5 files changed, 37 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 08fc706e3cbf74..19c60a8cb5e946 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -842,6 +842,8 @@ class FPOptions {
   /// Return difference with the given option set.
   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
 
+  void applyChanges(FPOptionsOverride FPO);
+
   // We can define most of the accessors automatically:
 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)
\
   TYPE get##NAME() const { 
\
@@ -923,6 +925,11 @@ class FPOptionsOverride {
   setAllowFPContractAcrossStatement();
   }
 
+  void setDisallowOptimizations() {
+setFPPreciseEnabled(true);
+setDisallowFPContract();
+  }
+
   storage_type getAsOpaqueInt() const {
 return (static_cast(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions &Base) const
   return getChangesSlow(Base);
 }
 
+inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
+  *this = FPO.applyOverrides(*this);
+}
+
 /// Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
   /// The translation unit is a complete translation unit.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 95ea5ebc7f1ac1..ccc2ded67589ec 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3222,6 +3222,7 @@ class Sema final {
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
 SkipBodyInfo *SkipBody = nullptr,
 FnBodyKind BodyKind = FnBodyKind::Other);
+  void applyFunctionAttributesBeforeParsingBody(Decl *FD);
 
   /// Determine whether we can delay parsing the body of a function or
   /// function template until it is used, assuming we don't care about emitting
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 76a3fa8f2627de..489ae9f167b95d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, 
ParseScope &BodyScope) {
   Sema::PragmaStackSentinelRAII
 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
 
+  // Some function attributes (like OptimizeNoneAttr) affect FP options.
+  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
+  Actions.applyFunctionAttributesBeforeParsingBody(Decl);
+
   // Do not enter a scope for the brace, as the arguments are in the same scope
   // (the function body) as the body itself.  Instead, just read the statement
   // list and put it into a CompoundStmt for safe keeping.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9aa..59c327515dba70 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope 
*FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD->hasAttr()) {
+FPOptionsOverride FPO;
+FPO.setDisallowOptimizations();
+CurFPFeatures.applyChanges(FPO);
+FpPragmaStack.CurrentValue =
+CurFPFeatures.getChangesFrom(FPOptions(LangOpts));
+  }
+}
+
 /// Given the set of return statements within a function body,
 /// compute the variables that are subject to the named return value
 /// optimization.
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp 
b/clang/test/AST/ast-dump-fpfeatures.cpp
index da0011602a728e..f6e9d3637417e6 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -187,3 +187,14 @@ float func_18(float x, float y) {
 // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff converted_to_draft 
https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/85605

>From 5049e0209e240f0f8a3ccb6e248d55d1480b7bad Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH] [clang] Set correct FPOptions if attribute 'optnone' presents

Attribute `optnone` must turn off all optimizations including fast-math
ones. Actually AST nodes in the 'optnone' function still had fast-math
flags. This change implements fixing FP options before function body is
parsed.
---
 clang/include/clang/Basic/LangOptions.h | 11 +++
 clang/include/clang/Sema/Sema.h |  1 +
 clang/lib/Parse/ParseStmt.cpp   |  4 
 clang/lib/Sema/SemaDecl.cpp | 10 ++
 clang/test/AST/ast-dump-fpfeatures.cpp  | 11 +++
 5 files changed, 37 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 08fc706e3cbf74..19c60a8cb5e946 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -842,6 +842,8 @@ class FPOptions {
   /// Return difference with the given option set.
   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
 
+  void applyChanges(FPOptionsOverride FPO);
+
   // We can define most of the accessors automatically:
 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)
\
   TYPE get##NAME() const { 
\
@@ -923,6 +925,11 @@ class FPOptionsOverride {
   setAllowFPContractAcrossStatement();
   }
 
+  void setDisallowOptimizations() {
+setFPPreciseEnabled(true);
+setDisallowFPContract();
+  }
+
   storage_type getAsOpaqueInt() const {
 return (static_cast(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions &Base) const
   return getChangesSlow(Base);
 }
 
+inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
+  *this = FPO.applyOverrides(*this);
+}
+
 /// Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
   /// The translation unit is a complete translation unit.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 95ea5ebc7f1ac1..ccc2ded67589ec 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3222,6 +3222,7 @@ class Sema final {
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
 SkipBodyInfo *SkipBody = nullptr,
 FnBodyKind BodyKind = FnBodyKind::Other);
+  void applyFunctionAttributesBeforeParsingBody(Decl *FD);
 
   /// Determine whether we can delay parsing the body of a function or
   /// function template until it is used, assuming we don't care about emitting
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 76a3fa8f2627de..489ae9f167b95d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, 
ParseScope &BodyScope) {
   Sema::PragmaStackSentinelRAII
 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
 
+  // Some function attributes (like OptimizeNoneAttr) affect FP options.
+  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
+  Actions.applyFunctionAttributesBeforeParsingBody(Decl);
+
   // Do not enter a scope for the brace, as the arguments are in the same scope
   // (the function body) as the body itself.  Instead, just read the statement
   // list and put it into a CompoundStmt for safe keeping.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9aa..1f52f5e57e5376 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope 
*FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD && FD->hasAttr()) {
+FPOptionsOverride FPO;
+FPO.setDisallowOptimizations();
+CurFPFeatures.applyChanges(FPO);
+FpPragmaStack.CurrentValue =
+CurFPFeatures.getChangesFrom(FPOptions(LangOpts));
+  }
+}
+
 /// Given the set of return statements within a function body,
 /// compute the variables that are subject to the named return value
 /// optimization.
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp 
b/clang/test/AST/ast-dump-fpfeatures.cpp
index da0011602a728e..5eda5528c07018 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -187,3 +187,14 @@ float func_18(float x, float y) {
 // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward
 // CHECK:   ReturnStmt
 // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward
+
+#pragma float_control(precise, off)
+__attribute__((optnone))
+float func_19(float x, float y) {
+  return x + y

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> Hmm. Is there some sort of optimization in IRGen that we need to suppress 
> here, or is it something in LLVM code gen? Presumably normal LLVM 
> optimization passes all just skip `optnone` functions.

The issue https://github.com/llvm/llvm-project/issues/62098 demonstrates such 
case. Anyway, It is not good to have bogus attributes in AST.

> Mostly I'm wondering how far we're expected to go with `optnone`.

It impedes implementation of pragma FENV_ROUND. The pragma requires setting FP 
options inside CompoundStmt and it interacts with the fictious attributes. This 
is the reason of this patch.



https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-19 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> optnone is a very strange attribute; it's a directive to the compiler with no 
> clear semantics.

`fast-math` also does not have clear semantics. It is however used to express 
user's expectations that some assumptions are valid. `optnone` could also be 
treated from similar viewpoint. It is very convenient for a user to have a "big 
switch" that would turn off "all" things that can complicate code generation. 
Which transformations are optimizations that should be turned off by optnone - 
it depends on user expectations. Fast-math options are definitely in this list, 
- they are unsafe transformations aimed at performance.

> And presumably they don't actually want to disable all optimization of their 
> function anyway; they just want to turn off fast math.

They can use `#pragma float_control(precise, on)`. However `optnone`, according 
to the documentation, is also a legitimate way to turn off fast math.

> I have uploaded your patch and compared the attributes generated from your 
> patch and the little test case from 
> https://github.com/llvm/llvm-project/issues/62098. The attributes generated 
> are different. Therefore, the expected optimizations from this patch are 
> going to be different than what we currently have. I think that's a problem.

Exactly. User specifies attribute `optnone` but the functions has attribute 
"no-infs-fp-math"="true", which is unsafe optimization. Even if this function 
is not transformed in IR pipeline, the attribute can cause CodeGen to emit code 
as if fast-math is in effect. Such behavior contradicts the meaning of 
`optnone` described in documenttion.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-19 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff ready_for_review 
https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-20 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/85605

>From 5049e0209e240f0f8a3ccb6e248d55d1480b7bad Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH 1/2] [clang] Set correct FPOptions if attribute 'optnone'
 presents

Attribute `optnone` must turn off all optimizations including fast-math
ones. Actually AST nodes in the 'optnone' function still had fast-math
flags. This change implements fixing FP options before function body is
parsed.
---
 clang/include/clang/Basic/LangOptions.h | 11 +++
 clang/include/clang/Sema/Sema.h |  1 +
 clang/lib/Parse/ParseStmt.cpp   |  4 
 clang/lib/Sema/SemaDecl.cpp | 10 ++
 clang/test/AST/ast-dump-fpfeatures.cpp  | 11 +++
 5 files changed, 37 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 08fc706e3cbf74..19c60a8cb5e946 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -842,6 +842,8 @@ class FPOptions {
   /// Return difference with the given option set.
   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
 
+  void applyChanges(FPOptionsOverride FPO);
+
   // We can define most of the accessors automatically:
 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)
\
   TYPE get##NAME() const { 
\
@@ -923,6 +925,11 @@ class FPOptionsOverride {
   setAllowFPContractAcrossStatement();
   }
 
+  void setDisallowOptimizations() {
+setFPPreciseEnabled(true);
+setDisallowFPContract();
+  }
+
   storage_type getAsOpaqueInt() const {
 return (static_cast(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions &Base) const
   return getChangesSlow(Base);
 }
 
+inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
+  *this = FPO.applyOverrides(*this);
+}
+
 /// Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
   /// The translation unit is a complete translation unit.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 95ea5ebc7f1ac1..ccc2ded67589ec 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3222,6 +3222,7 @@ class Sema final {
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
 SkipBodyInfo *SkipBody = nullptr,
 FnBodyKind BodyKind = FnBodyKind::Other);
+  void applyFunctionAttributesBeforeParsingBody(Decl *FD);
 
   /// Determine whether we can delay parsing the body of a function or
   /// function template until it is used, assuming we don't care about emitting
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 76a3fa8f2627de..489ae9f167b95d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, 
ParseScope &BodyScope) {
   Sema::PragmaStackSentinelRAII
 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
 
+  // Some function attributes (like OptimizeNoneAttr) affect FP options.
+  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
+  Actions.applyFunctionAttributesBeforeParsingBody(Decl);
+
   // Do not enter a scope for the brace, as the arguments are in the same scope
   // (the function body) as the body itself.  Instead, just read the statement
   // list and put it into a CompoundStmt for safe keeping.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9aa..1f52f5e57e5376 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope 
*FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD && FD->hasAttr()) {
+FPOptionsOverride FPO;
+FPO.setDisallowOptimizations();
+CurFPFeatures.applyChanges(FPO);
+FpPragmaStack.CurrentValue =
+CurFPFeatures.getChangesFrom(FPOptions(LangOpts));
+  }
+}
+
 /// Given the set of return statements within a function body,
 /// compute the variables that are subject to the named return value
 /// optimization.
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp 
b/clang/test/AST/ast-dump-fpfeatures.cpp
index da0011602a728e..5eda5528c07018 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -187,3 +187,14 @@ float func_18(float x, float y) {
 // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward
 // CHECK:   ReturnStmt
 // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward
+
+#pragma float_control(precise, off)
+__attribute__((optnone))
+float func_19(float x, float y) {
+  return 

  1   2   3   4   5   >