[cfe-commits] r112361 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/ASTImporter.cpp lib/AST/Expr.cpp lib/Rewrite/RewriteObjC.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Sat Aug 28 02:06:06 PDT 2010


Author: akirtzidis
Date: Sat Aug 28 04:06:06 2010
New Revision: 112361

URL: http://llvm.org/viewvc/llvm-project?rev=112361&view=rev
Log:
Fix the memory leak of FloatingLiteral/IntegerLiteral.

For large floats/integers, APFloat/APInt will allocate memory from the heap to represent these numbers.
Unfortunately, when we use a BumpPtrAllocator to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
the APFloat/APInt values will never get freed.
I introduce the class 'APNumericStorage' which uses ASTContext's allocator for memory allocation and is used internally by FloatingLiteral/IntegerLiteral.

Fixes rdar://7637185

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Rewrite/RewriteObjC.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Aug 28 04:06:06 2010
@@ -757,28 +757,84 @@
   virtual child_iterator child_end();
 };
 
+/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
+/// leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers.  Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+  unsigned BitWidth;
+  union {
+    uint64_t VAL;    ///< Used to store the <= 64 bits integer value.
+    uint64_t *pVal;  ///< Used to store the >64 bits integer value.
+  };
+
+  bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+  APNumericStorage(const APNumericStorage&); // do not implement
+  APNumericStorage& operator=(const APNumericStorage&); // do not implement
+
+protected:
+  APNumericStorage() : BitWidth(0), VAL(0) { }
+
+  llvm::APInt getIntValue() const {
+    unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+    if (NumWords > 1)
+      return llvm::APInt(BitWidth, NumWords, pVal);
+    else
+      return llvm::APInt(BitWidth, VAL);
+  }
+  void setIntValue(ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : public APNumericStorage {
+public:  
+  llvm::APInt getValue() const { return getIntValue(); } 
+  void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); }
+};
+
+class APFloatStorage : public APNumericStorage {
+public:  
+  llvm::APFloat getValue() const { return llvm::APFloat(getIntValue()); } 
+  void setValue(ASTContext &C, const llvm::APFloat &Val) {
+    setIntValue(C, Val.bitcastToAPInt());
+  }
+};
+
 class IntegerLiteral : public Expr {
-  llvm::APInt Value;
+  APIntStorage Num;
   SourceLocation Loc;
+
+  /// \brief Construct an empty integer literal.
+  explicit IntegerLiteral(EmptyShell Empty)
+    : Expr(IntegerLiteralClass, Empty) { }
+
 public:
   // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
   // or UnsignedLongLongTy
-  IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
-    : Expr(IntegerLiteralClass, type, false, false), Value(V), Loc(l) {
+  IntegerLiteral(ASTContext &C, const llvm::APInt &V,
+                 QualType type, SourceLocation l)
+    : Expr(IntegerLiteralClass, type, false, false), Loc(l) {
     assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+    setValue(C, V);
   }
 
-  /// \brief Construct an empty integer literal.
-  explicit IntegerLiteral(EmptyShell Empty)
-    : Expr(IntegerLiteralClass, Empty) { }
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+  // or UnsignedLongLongTy
+  static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V,
+                                QualType type, SourceLocation l);
+  static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
 
-  const llvm::APInt &getValue() const { return Value; }
+  llvm::APInt getValue() const { return Num.getValue(); }
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
   /// \brief Retrieve the location of the literal.
   SourceLocation getLocation() const { return Loc; }
 
-  void setValue(const llvm::APInt &Val) { Value = Val; }
+  void setValue(ASTContext &C, const llvm::APInt &Val) { Num.setValue(C, Val); }
   void setLocation(SourceLocation Location) { Loc = Location; }
 
   static bool classof(const Stmt *T) {
@@ -827,21 +883,30 @@
 };
 
 class FloatingLiteral : public Expr {
-  llvm::APFloat Value;
+  APFloatStorage Num;
   bool IsExact : 1;
   SourceLocation Loc;
-public:
-  FloatingLiteral(const llvm::APFloat &V, bool isexact,
+
+  FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
                   QualType Type, SourceLocation L)
-    : Expr(FloatingLiteralClass, Type, false, false), Value(V),
-      IsExact(isexact), Loc(L) {}
+    : Expr(FloatingLiteralClass, Type, false, false),
+      IsExact(isexact), Loc(L) {
+    setValue(C, V);
+  }
 
   /// \brief Construct an empty floating-point literal.
   explicit FloatingLiteral(EmptyShell Empty)
-    : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+    : Expr(FloatingLiteralClass, Empty), IsExact(false) { }
+
+public:
+  static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V,
+                                 bool isexact, QualType Type, SourceLocation L);
+  static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
 
-  const llvm::APFloat &getValue() const { return Value; }
-  void setValue(const llvm::APFloat &Val) { Value = Val; }
+  llvm::APFloat getValue() const { return Num.getValue(); }
+  void setValue(ASTContext &C, const llvm::APFloat &Val) {
+    Num.setValue(C, Val);
+  }
 
   bool isExact() const { return IsExact; }
   void setExact(bool E) { IsExact = E; }

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sat Aug 28 04:06:06 2010
@@ -2818,8 +2818,9 @@
   if (T.isNull())
     return 0;
 
-  return new (Importer.getToContext()) 
-    IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
+  return IntegerLiteral::Create(Importer.getToContext(), 
+                                E->getValue(), T,
+                                Importer.Import(E->getLocation()));
 }
 
 Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Aug 28 04:06:06 2010
@@ -374,6 +374,44 @@
   return "";
 }
 
+void APNumericStorage::setIntValue(ASTContext &C, const llvm::APInt &Val) {
+  if (hasAllocation())
+    C.Deallocate(pVal);
+
+  BitWidth = Val.getBitWidth();
+  unsigned NumWords = Val.getNumWords();
+  const uint64_t* Words = Val.getRawData();
+  if (NumWords > 1) {
+    pVal = new (C) uint64_t[NumWords];
+    std::copy(Words, Words + NumWords, pVal);
+  } else if (NumWords == 1)
+    VAL = Words[0];
+  else
+    VAL = 0;
+}
+
+IntegerLiteral *
+IntegerLiteral::Create(ASTContext &C, const llvm::APInt &V,
+                       QualType type, SourceLocation l) {
+  return new (C) IntegerLiteral(C, V, type, l);
+}
+
+IntegerLiteral *
+IntegerLiteral::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) IntegerLiteral(Empty);
+}
+
+FloatingLiteral *
+FloatingLiteral::Create(ASTContext &C, const llvm::APFloat &V,
+                        bool isexact, QualType Type, SourceLocation L) {
+  return new (C) FloatingLiteral(C, V, isexact, Type, L);
+}
+
+FloatingLiteral *
+FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) FloatingLiteral(Empty);
+}
+
 /// getValueAsApproximateDouble - This returns the value as an inaccurate
 /// double.  Note that this may cause loss of precision, but is useful for
 /// debugging dumps, etc.

Modified: cfe/trunk/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteObjC.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteObjC.cpp Sat Aug 28 04:06:06 2010
@@ -3029,9 +3029,10 @@
     // is needed to decide what to do.
     unsigned IntSize =
       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-    IntegerLiteral *limit = new (Context) IntegerLiteral(llvm::APInt(IntSize, 8),
-                                               Context->IntTy,
-                                               SourceLocation());
+    IntegerLiteral *limit = IntegerLiteral::Create(*Context,
+                                                   llvm::APInt(IntSize, 8),
+                                                   Context->IntTy,
+                                                   SourceLocation());
     BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit,
                                                       BO_LE,
                                                       Context->IntTy,
@@ -5268,8 +5269,8 @@
     int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
     unsigned IntSize = 
       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-    Expr *FlagExp = new (Context) IntegerLiteral(llvm::APInt(IntSize, flag), 
-                                             Context->IntTy, SourceLocation());
+    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
+                                           Context->IntTy, SourceLocation());
     InitExprs.push_back(FlagExp);
   }
   NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Aug 28 04:06:06 2010
@@ -6480,8 +6480,7 @@
   }
   // All conditions are met. Add a new bitfield to the tail end of ivars.
   llvm::APInt Zero(Context.getTypeSize(Context.CharTy), 0);
-  Expr * BW = 
-    new (Context) IntegerLiteral(Zero, Context.CharTy, DeclLoc);
+  Expr * BW = IntegerLiteral::Create(Context, Zero, Context.CharTy, DeclLoc);
 
   Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
                               DeclLoc, 0,

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Aug 28 04:06:06 2010
@@ -4669,7 +4669,7 @@
   
   // Initialize the iteration variable to zero.
   llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0);
-  IterationVar->setInit(new (S.Context) IntegerLiteral(Zero, SizeType, Loc));
+  IterationVar->setInit(IntegerLiteral::Create(S.Context, Zero, SizeType, Loc));
 
   // Create a reference to the iteration variable; we'll use this several
   // times throughout.
@@ -4685,8 +4685,9 @@
   Upper.zextOrTrunc(S.Context.getTypeSize(SizeType));
   Expr *Comparison
     = new (S.Context) BinaryOperator(IterationVarRef->Retain(),
-                           new (S.Context) IntegerLiteral(Upper, SizeType, Loc),
-                                    BO_NE, S.Context.BoolTy, Loc);
+                           IntegerLiteral::Create(S.Context,
+                                                  Upper, SizeType, Loc),
+                                                  BO_NE, S.Context.BoolTy, Loc);
   
   // Create the pre-increment of the iteration variable.
   Expr *Increment
@@ -5135,7 +5136,7 @@
       ASTOwningVector<Expr*> CallArgs(*this);
       CallArgs.push_back(To.takeAs<Expr>());
       CallArgs.push_back(From.takeAs<Expr>());
-      CallArgs.push_back(new (Context) IntegerLiteral(Size, SizeType, Loc));
+      CallArgs.push_back(IntegerLiteral::Create(Context, Size, SizeType, Loc));
       llvm::SmallVector<SourceLocation, 4> Commas; // FIXME: Silly
       Commas.push_back(Loc);
       Commas.push_back(Loc);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Aug 28 04:06:06 2010
@@ -1946,7 +1946,7 @@
   if (Tok.getLength() == 1) {
     const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
     unsigned IntSize = Context.Target.getIntWidth();
-    return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
+    return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
                     Context.IntTy, Tok.getLocation()));
   }
 
@@ -2004,7 +2004,7 @@
     }
 
     bool isExact = (result == APFloat::opOK);
-    Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+    Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
 
   } else if (!Literal.isIntegerLiteral()) {
     return ExprError();
@@ -2091,7 +2091,7 @@
       if (ResultVal.getBitWidth() != Width)
         ResultVal.trunc(Width);
     }
-    Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+    Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
   }
 
   // If this is an imaginary literal, create the ImaginaryLiteral wrapper.

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Aug 28 04:06:06 2010
@@ -672,9 +672,9 @@
   if (!ArraySize) {
     if (const ConstantArrayType *Array
                               = Context.getAsConstantArrayType(AllocType)) {
-      ArraySize = new (Context) IntegerLiteral(Array->getSize(),
-                                               Context.getSizeType(),
-                                               TypeRange.getEnd());
+      ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
+                                         Context.getSizeType(),
+                                         TypeRange.getEnd());
       AllocType = Array->getElementType();
     }
   }
@@ -922,7 +922,7 @@
   // We don't care about the actual value of this argument.
   // FIXME: Should the Sema create the expression and embed it in the syntax
   // tree? Or should the consumer just recalculate the value?
-  IntegerLiteral Size(llvm::APInt::getNullValue(
+  IntegerLiteral Size(Context, llvm::APInt::getNullValue(
                       Context.Target.getPointerWidth(0)),
                       Context.getSizeType(),
                       SourceLocation());

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Aug 28 04:06:06 2010
@@ -6754,8 +6754,8 @@
   // post-decrement.
   if (Opc == UO_PostInc || Opc == UO_PostDec) {
     llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
-    Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
-                                           SourceLocation());
+    Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy,
+                                     SourceLocation());
     NumArgs = 2;
   }
 

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Aug 28 04:06:06 2010
@@ -3149,7 +3149,7 @@
                                             T,
                                             Loc));
 
-  return Owned(new (Context) IntegerLiteral(*Arg.getAsIntegral(), T, Loc));
+  return Owned(IntegerLiteral::Create(Context, *Arg.getAsIntegral(), T, Loc));
 }
 
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sat Aug 28 04:06:06 2010
@@ -5332,10 +5332,10 @@
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
       ArraySize 
-        = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
-                                                  ConsArrayT->getSize(), 
-                                                  SemaRef.Context.getSizeType(),
-                                                  /*FIXME:*/E->getLocStart()));
+        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
+                                               ConsArrayT->getSize(), 
+                                               SemaRef.Context.getSizeType(),
+                                               /*FIXME:*/E->getLocStart()));
       AllocType = ConsArrayT->getElementType();
     } else if (const DependentSizedArrayType *DepArrayT
                               = dyn_cast<DependentSizedArrayType>(ArrayT)) {
@@ -6352,7 +6352,8 @@
       break;
     }
 
-  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
+  IntegerLiteral ArraySize(SemaRef.Context, *Size, SizeType,
+                           /*FIXME*/BracketsRange.getBegin());
   return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
                                 IndexTypeQuals, BracketsRange,
                                 getDerived().getBaseEntity());
@@ -6418,8 +6419,8 @@
   llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
                           NumElements, true);
   IntegerLiteral *VectorSize
-    = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
-                                           AttributeLoc);
+    = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
+                             AttributeLoc);
   return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=112361&r1=112360&r2=112361&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sat Aug 28 04:06:06 2010
@@ -409,12 +409,12 @@
 void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
   VisitExpr(E);
   E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  E->setValue(Reader.ReadAPInt(Record, Idx));
+  E->setValue(*Reader.getContext(), Reader.ReadAPInt(Record, Idx));
 }
 
 void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
   VisitExpr(E);
-  E->setValue(Reader.ReadAPFloat(Record, Idx));
+  E->setValue(*Reader.getContext(), Reader.ReadAPFloat(Record, Idx));
   E->setExact(Record[Idx++]);
   E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
@@ -1401,11 +1401,11 @@
       break;
 
     case EXPR_INTEGER_LITERAL:
-      S = new (Context) IntegerLiteral(Empty);
+      S = IntegerLiteral::Create(*Context, Empty);
       break;
 
     case EXPR_FLOATING_LITERAL:
-      S = new (Context) FloatingLiteral(Empty);
+      S = FloatingLiteral::Create(*Context, Empty);
       break;
 
     case EXPR_IMAGINARY_LITERAL:





More information about the cfe-commits mailing list