forked from OSchip/llvm-project
				
			Fix a few cases where enum constant handling was using
ASTContext::getTypeSize() rather than ASTContext::getIntWidth() for the width of an integral type. The former includes padding for bools (to the target's size) while the latter does not, so we woud end up zero-extending bools to the target width when we shouldn't. Fixes a crash-on-valid in the included test. llvm-svn: 101372
This commit is contained in:
		
							parent
							
								
									ff3c8b7eaf
								
							
						
					
					
						commit
						c1cf814c8b
					
				| 
						 | 
				
			
			@ -6006,7 +6006,7 @@ static bool isRepresentableIntegerValue(ASTContext &Context,
 | 
			
		|||
                                        llvm::APSInt &Value,
 | 
			
		||||
                                        QualType T) {
 | 
			
		||||
  assert(T->isIntegralType() && "Integral type required!");
 | 
			
		||||
  unsigned BitWidth = Context.getTypeSize(T);
 | 
			
		||||
  unsigned BitWidth = Context.getIntWidth(T);
 | 
			
		||||
  
 | 
			
		||||
  if (Value.isUnsigned() || Value.isNonNegative())
 | 
			
		||||
    return Value.getActiveBits() < BitWidth;
 | 
			
		||||
| 
						 | 
				
			
			@ -6139,7 +6139,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
 | 
			
		|||
        // value, then increment.
 | 
			
		||||
        EnumVal = LastEnumConst->getInitVal();
 | 
			
		||||
        EnumVal.setIsSigned(EltTy->isSignedIntegerType());
 | 
			
		||||
        EnumVal.zextOrTrunc(Context.getTypeSize(EltTy));
 | 
			
		||||
        EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
 | 
			
		||||
        ++EnumVal;        
 | 
			
		||||
        
 | 
			
		||||
        // If we're not in C++, diagnose the overflow of enumerator values,
 | 
			
		||||
| 
						 | 
				
			
			@ -6161,7 +6161,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
 | 
			
		|||
  if (!EltTy->isDependentType()) {
 | 
			
		||||
    // Make the enumerator value match the signedness and size of the 
 | 
			
		||||
    // enumerator's type.
 | 
			
		||||
    EnumVal.zextOrTrunc(Context.getTypeSize(EltTy));
 | 
			
		||||
    EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
 | 
			
		||||
    EnumVal.setIsSigned(EltTy->isSignedIntegerType());
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 | 
			
		||||
 | 
			
		||||
// C++ [expr.const]p1:
 | 
			
		||||
//   In several places, C++ requires expressions that evaluate to an integral
 | 
			
		||||
//   or enumeration constant: as array bounds, as case expressions, as
 | 
			
		||||
| 
						 | 
				
			
			@ -79,5 +78,10 @@ template <int itval, Enum etval> struct C {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
template struct C<1, eval>;
 | 
			
		||||
//template struct C<cval, ceval>;
 | 
			
		||||
//template struct C<Struct::sval, Struct::seval>;
 | 
			
		||||
template struct C<cval, ceval>;
 | 
			
		||||
template struct C<Struct::sval, Struct::seval>;
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  a = sizeof(int) == 8,
 | 
			
		||||
  b = a? 8 : 4
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue