Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(401)

Side by Side Diff: lib/Bitcode/NaCl/Analysis/NaClObjDump.cpp

Issue 807643002: Don't allow instructions/globals to use alignment > 2**29. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix issues in patch set 5. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===// 1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 9
10 #include "llvm/ADT/STLExtras.h" 10 #include "llvm/ADT/STLExtras.h"
(...skipping 21 matching lines...) Expand all
32 namespace { 32 namespace {
33 33
34 using namespace llvm; 34 using namespace llvm;
35 35
36 static cl::opt<bool> 36 static cl::opt<bool>
37 ReportWarningsAsErrors( 37 ReportWarningsAsErrors(
38 "Werror", 38 "Werror",
39 cl::desc("Report warnings as errors."), 39 cl::desc("Report warnings as errors."),
40 cl::init(false)); 40 cl::init(false));
41 41
42 static cl::opt<bool>
43 IgnorePNaClABIChecks(
44 "ignore-pnaclabi-checks",
45 cl::desc("Ignore checking bitcode for PNaCl ABI violations"),
46 cl::init(false));
47
42 /// Class to handle sign rotations in a human readable form. That is, 48 /// Class to handle sign rotations in a human readable form. That is,
43 /// the sign is in the low bit. The two special cases are: 49 /// the sign is in the low bit. The two special cases are:
44 /// 1) -1 is true for i1. 50 /// 1) -1 is true for i1.
45 /// 2) The representation allows -0 (which is different than 0). 51 /// 2) The representation allows -0 (which is different than 0).
46 class SignRotatedInt { 52 class SignRotatedInt {
47 public: 53 public:
48 SignRotatedInt(uint64_t Value, Type* ValueType) 54 SignRotatedInt(uint64_t Value, Type* ValueType)
49 : SignedValue(Value >> 1), 55 : SignedValue(Value >> 1),
50 IsNegated((Value & 0x1) 56 IsNegated((Value & 0x1)
51 && !(ValueType->isIntegerTy() 57 && !(ValueType->isIntegerTy()
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 } 932 }
927 933
928 /// Increments the current number of defined global abbreviations. 934 /// Increments the current number of defined global abbreviations.
929 void IncNumGlobalAbbreviations(unsigned BlockID) { 935 void IncNumGlobalAbbreviations(unsigned BlockID) {
930 ++GlobalAbbrevsCountMap[BlockID]; 936 ++GlobalAbbrevsCountMap[BlockID];
931 } 937 }
932 938
933 /// Verifies the given integer operator has the right type. Returns 939 /// Verifies the given integer operator has the right type. Returns
934 /// the operator. 940 /// the operator.
935 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) { 941 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) {
936 if (!PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) { 942 if (!IgnorePNaClABIChecks &&
943 !PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) {
937 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy; 944 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy;
938 } 945 }
939 return Op; 946 return Op;
940 } 947 }
941 948
942 // Checks the Alignment for loading/storing a value of type Ty. If 949 // Checks the Alignment for loading/storing a value of type Ty. If
943 // invalid, generates an appropriate error message. 950 // invalid, generates an appropriate error message.
944 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty, 951 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty,
945 uint64_t Alignment) { 952 unsigned Alignment) {
953 if (IgnorePNaClABIChecks) return;
946 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) { 954 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) {
947 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) { 955 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) {
948 Errors() << Op << ": Illegal alignment for " << *Ty 956 Errors() << Op << ": Illegal alignment for " << *Ty
949 << ". Expects: " << Expected << "\n"; 957 << ". Expects: " << Expected << "\n";
950 } else { 958 } else {
951 Errors() << Op << ": Not allowed for type: " << *Ty << "\n"; 959 Errors() << Op << ": Not allowed for type: " << *Ty << "\n";
952 } 960 }
953 } 961 }
954 } 962 }
955 963
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 Errors() << "Integer record should have one argument. Found: " 1798 Errors() << "Integer record should have one argument. Found: "
1791 << Values.size() << "\n"; 1799 << Values.size() << "\n";
1792 Size = 32; 1800 Size = 32;
1793 } 1801 }
1794 switch (Size) { 1802 switch (Size) {
1795 case 1: 1803 case 1:
1796 case 8: 1804 case 8:
1797 case 16: 1805 case 16:
1798 case 32: 1806 case 32:
1799 case 64: { 1807 case 64: {
1800 break; 1808 break;
1809 }
1810 default:
1811 if (!IgnorePNaClABIChecks) {
1812 Errors() << "Integer record contains bad integer size: "
1813 << Size << "\n";
1814 Size = 32;
1801 } 1815 }
1802 default:
1803 Errors() << "Integer record contains bad integer size: "
1804 << Size << "\n";
1805 Size = 32;
1806 break; 1816 break;
1807 } 1817 }
1808 Type *IntType = GetIntegerType(Size); 1818 Type *IntType = GetIntegerType(Size);
1809 Tokens() << NextTypeId() << Space() << "=" << Space() 1819 Tokens() << NextTypeId() << Space() << "=" << Space()
1810 << TokenizeType(IntType) << Semicolon() 1820 << TokenizeType(IntType) << Semicolon()
1811 << TokenizeAbbrevIndex() << Endline(); 1821 << TokenizeAbbrevIndex() << Endline();
1812 InstallType(IntType); 1822 InstallType(IntType);
1813 break; 1823 break;
1814 } 1824 }
1815 case naclbitc::TYPE_CODE_VECTOR: { 1825 case naclbitc::TYPE_CODE_VECTOR: {
1816 // VECTOR: [numelts, eltty] 1826 // VECTOR: [numelts, eltty]
1817 if (Values.size() != 2) { 1827 if (Values.size() != 2) {
1818 Errors() << "Vector record should contain two arguments. Found: " 1828 Errors() << "Vector record should contain two arguments. Found: "
1819 << Values.size() << "\n"; 1829 << Values.size() << "\n";
1820 InstallUnknownTypeForNextId(); 1830 InstallUnknownTypeForNextId();
1821 break; 1831 break;
1822 } 1832 }
1823 Type *BaseType = GetType(Values[1]); 1833 Type *BaseType = GetType(Values[1]);
1824 if (!(BaseType->isIntegerTy() 1834 if (!(BaseType->isIntegerTy()
1825 || BaseType->isFloatTy() 1835 || BaseType->isFloatTy()
1826 || BaseType->isDoubleTy())) { 1836 || BaseType->isDoubleTy())) {
1827 Type *ErrorRecoveryTy = GetIntegerType(32); 1837 Type *ErrorRecoveryTy = GetIntegerType(32);
1828 Errors() << "Vectors can only be defined on primitive types. Found " 1838 Errors() << "Vectors can only be defined on primitive types. Found "
1829 << *BaseType << ". Assuming " << *ErrorRecoveryTy 1839 << *BaseType << ". Assuming " << *ErrorRecoveryTy
1830 << " instead.\n"; 1840 << " instead.\n";
1831 BaseType = ErrorRecoveryTy; 1841 BaseType = ErrorRecoveryTy;
1832 } 1842 }
1833 uint64_t NumElements = Values[0]; 1843 uint64_t NumElements = Values[0];
1834 Type *VecType = VectorType::get(BaseType, NumElements); 1844 Type *VecType = VectorType::get(BaseType, NumElements);
1835 if (!PNaClABITypeChecker::isValidVectorType(VecType)) { 1845 if (!IgnorePNaClABIChecks &&
1846 !PNaClABITypeChecker::isValidVectorType(VecType)) {
1836 Errors() << "Vector type " << *VecType << " not allowed.\n"; 1847 Errors() << "Vector type " << *VecType << " not allowed.\n";
1837 } 1848 }
1838 Tokens() << NextTypeId() << Space() << "=" << Space() 1849 Tokens() << NextTypeId() << Space() << "=" << Space()
1839 << TokenizeType(VecType) << Semicolon() 1850 << TokenizeType(VecType) << Semicolon()
1840 << TokenizeAbbrevIndex() << Endline(); 1851 << TokenizeAbbrevIndex() << Endline();
1841 InstallType(VecType); 1852 InstallType(VecType);
1842 break; 1853 break;
1843 } 1854 }
1844 case naclbitc::TYPE_CODE_FUNCTION: { 1855 case naclbitc::TYPE_CODE_FUNCTION: {
1845 // FUNCTION: [vararg, retty, paramty x N] 1856 // FUNCTION: [vararg, retty, paramty x N]
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 // Verify that expected intrinsic function type matches declared 2211 // Verify that expected intrinsic function type matches declared
2201 // type signature. 2212 // type signature.
2202 FunctionType *FcnTy = GetFunctionType(ValID); 2213 FunctionType *FcnTy = GetFunctionType(ValID);
2203 if (FcnTy->getNumParams() != IntrinTy->getNumParams()) { 2214 if (FcnTy->getNumParams() != IntrinTy->getNumParams()) {
2204 Errors() << "Intrinsic " << Name 2215 Errors() << "Intrinsic " << Name
2205 << " expects " << IntrinTy->getNumParams() 2216 << " expects " << IntrinTy->getNumParams()
2206 << " arguments. Found: " << FcnTy->getNumParams() 2217 << " arguments. Found: " << FcnTy->getNumParams()
2207 << "\n"; 2218 << "\n";
2208 break; 2219 break;
2209 } 2220 }
2210 if (!PNaClABITypeChecker::IsPointerEquivType( 2221 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2211 IntrinTy->getReturnType(), FcnTy->getReturnType())) { 2222 IntrinTy->getReturnType(), FcnTy->getReturnType())) {
2212 Errors() << "Intrinsic " << Name 2223 Errors() << "Intrinsic " << Name
2213 << " expects return type " << *IntrinTy->getReturnType() 2224 << " expects return type " << *IntrinTy->getReturnType()
2214 << ". Found: " << *FcnTy->getReturnType() << "\n"; 2225 << ". Found: " << *FcnTy->getReturnType() << "\n";
2215 break; 2226 break;
2216 } 2227 }
2217 for (size_t i = 0; i < FcnTy->getNumParams(); ++i) { 2228 for (size_t i = 0; i < FcnTy->getNumParams(); ++i) {
2218 if (!PNaClABITypeChecker::IsPointerEquivType( 2229 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2219 IntrinTy->getParamType(i), 2230 IntrinTy->getParamType(i),
2220 FcnTy->getParamType(i))) { 2231 FcnTy->getParamType(i))) {
2221 Errors() << "Intrinsic " << Name 2232 Errors() << "Intrinsic " << Name
2222 << " expects " << *IntrinTy->getParamType(i) 2233 << " expects " << *IntrinTy->getParamType(i)
2223 << " for argument " << (i+1) << ". Found: " 2234 << " for argument " << (i+1) << ". Found: "
2224 << *FcnTy->getParamType(i) << "\n"; 2235 << *FcnTy->getParamType(i) << "\n";
2225 break; 2236 break;
2226 } 2237 }
2227 } 2238 }
2228 } 2239 }
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2467
2457 bool isFloatingType(Type *Ty) { 2468 bool isFloatingType(Type *Ty) {
2458 return Ty->isFloatTy() || Ty->isDoubleTy(); 2469 return Ty->isFloatTy() || Ty->isDoubleTy();
2459 } 2470 }
2460 2471
2461 /// Verifies that OpTy is an integer, or a vector of integers, for 2472 /// Verifies that OpTy is an integer, or a vector of integers, for
2462 /// operator Op. Generates error messages if appropriate. Returns Op. 2473 /// operator Op. Generates error messages if appropriate. Returns Op.
2463 const char *VerifyIntegerOrVectorOp(const char *Op, Type *OpTy) { 2474 const char *VerifyIntegerOrVectorOp(const char *Op, Type *OpTy) {
2464 Type *BaseTy = OpTy; 2475 Type *BaseTy = OpTy;
2465 if (OpTy->isVectorTy()) { 2476 if (OpTy->isVectorTy()) {
2466 if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2477 if (!IgnorePNaClABIChecks &&
2478 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2467 Errors() << Op << ": invalid vector type: " << *OpTy << "\n"; 2479 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2468 return Op; 2480 return Op;
2469 } 2481 }
2470 BaseTy = OpTy->getVectorElementType(); 2482 BaseTy = OpTy->getVectorElementType();
2471 } 2483 }
2472 if (BaseTy->isIntegerTy()) { 2484 if (BaseTy->isIntegerTy()) {
2473 if (PNaClABITypeChecker::isValidScalarType(BaseTy)) return Op; 2485 if (IgnorePNaClABIChecks ||
2486 PNaClABITypeChecker::isValidScalarType(BaseTy)) {
2487 return Op;
2488 }
2474 Errors() << Op << ": Invalid integer type: " << *OpTy << "\n"; 2489 Errors() << Op << ": Invalid integer type: " << *OpTy << "\n";
2475 } else { 2490 } else {
2476 Errors() << Op << ": Expects integer type. Found: " << *OpTy << "\n"; 2491 Errors() << Op << ": Expects integer type. Found: " << *OpTy << "\n";
2477 } 2492 }
2478 return Op; 2493 return Op;
2479 } 2494 }
2480 2495
2481 /// Verifies that Opty is a floating point type, or a vector of a 2496 /// Verifies that Opty is a floating point type, or a vector of a
2482 /// floating points, for operator Op. Generates error messages if 2497 /// floating points, for operator Op. Generates error messages if
2483 /// appropriate. Returns Op. 2498 /// appropriate. Returns Op.
2484 const char *VerifyFloatingOrVectorOp(const char *Op, Type *OpTy) { 2499 const char *VerifyFloatingOrVectorOp(const char *Op, Type *OpTy) {
2485 Type *BaseTy = OpTy; 2500 Type *BaseTy = OpTy;
2486 if (OpTy->isVectorTy()) { 2501 if (OpTy->isVectorTy()) {
2487 if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2502 if (!IgnorePNaClABIChecks &&
2503 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2488 Errors() << Op << ": invalid vector type: " << *OpTy << "\n"; 2504 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2489 return Op; 2505 return Op;
2490 } 2506 }
2491 BaseTy = OpTy->getVectorElementType(); 2507 BaseTy = OpTy->getVectorElementType();
2492 } 2508 }
2493 if (!isFloatingType(BaseTy)) { 2509 if (!isFloatingType(BaseTy)) {
2494 Errors() << Op << ": Expects floating point. Found " 2510 Errors() << Op << ": Expects floating point. Found "
2495 << OpTy << "\n"; 2511 << OpTy << "\n";
2496 return Op; 2512 return Op;
2497 } 2513 }
2498 if (!PNaClABITypeChecker::isValidScalarType(BaseTy)) { 2514 if (!IgnorePNaClABIChecks &&
2515 !PNaClABITypeChecker::isValidScalarType(BaseTy)) {
2499 Errors() << Op << ": type not allowed: " << OpTy << "\n"; 2516 Errors() << Op << ": type not allowed: " << OpTy << "\n";
2500 } 2517 }
2501 return Op; 2518 return Op;
2502 } 2519 }
2503 2520
2504 /// Op is the name of the operation that called this. Checks if 2521 /// Op is the name of the operation that called this. Checks if
2505 /// OpTy is either a (non-void) scalar, or a vector of scalars. If 2522 /// OpTy is either a (non-void) scalar, or a vector of scalars. If
2506 /// not, generates an appropriate error message. Always returns Op. 2523 /// not, generates an appropriate error message. Always returns Op.
2507 const char *VerifyScalarOrVectorOp(const char *Op, Type *OpTy) { 2524 const char *VerifyScalarOrVectorOp(const char *Op, Type *OpTy) {
2525 if (IgnorePNaClABIChecks) return Op;
2508 if (PNaClABITypeChecker::isValidScalarType(OpTy)) { 2526 if (PNaClABITypeChecker::isValidScalarType(OpTy)) {
2509 if (OpTy->isVoidTy()) 2527 if (OpTy->isVoidTy())
2510 Errors() << Op << ": Type void not allowed\n"; 2528 Errors() << Op << ": Type void not allowed\n";
2511 } else if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2529 } else if (!PNaClABITypeChecker::isValidVectorType(OpTy)) {
2512 Errors() << Op << ": Expects scalar/vector type. Found: " 2530 Errors() << Op << ": Expects scalar/vector type. Found: "
2513 << OpTy << "\n"; 2531 << OpTy << "\n";
2514 } 2532 }
2515 return Op; 2533 return Op;
2516 } 2534 }
2517 2535
2518 void VerifyIndexedVector(const char *Op, uint32_t VecValue, 2536 void VerifyIndexedVector(const char *Op, uint32_t VecValue,
2519 uint32_t IdxValue) { 2537 uint32_t IdxValue) {
2520 Type *VecType = GetValueType(VecValue); 2538 Type *VecType = GetValueType(VecValue);
2521 Type *IdxType = GetValueType(IdxValue); 2539 Type *IdxType = GetValueType(IdxValue);
2522 if (!PNaClABITypeChecker::isValidVectorType(VecType)){ 2540 if (!IgnorePNaClABIChecks &&
2541 !PNaClABITypeChecker::isValidVectorType(VecType)){
2523 if (VecType->isVectorTy()) 2542 if (VecType->isVectorTy())
2524 Errors() << Op << ": Vector type " << *VecType << " not allowed\n"; 2543 Errors() << Op << ": Vector type " << *VecType << " not allowed\n";
2525 else 2544 else
2526 Errors() << Op << ": Vector type expected. Found: " << *VecType << "\n"; 2545 Errors() << Op << ": Vector type expected. Found: " << *VecType << "\n";
2527 } 2546 }
2528 // Note: This restriction appears to be LLVM specific. 2547 // Note: This restriction appears to be LLVM specific.
2529 if (!IdxType->isIntegerTy(32)) { 2548 if (!IdxType->isIntegerTy(32)) {
2530 Errors() << Op << ": Index not i32. Found: " << *IdxType << "\n"; 2549 Errors() << Op << ": Index not i32. Found: " << *IdxType << "\n";
2531 } 2550 }
2532 BitcodeId IdxId(GetBitcodeId(IdxValue)); 2551 BitcodeId IdxId(GetBitcodeId(IdxValue));
2533 if (IdxId.GetKind() != 'c') { 2552 if (IdxId.GetKind() != 'c') {
2534 Errors() << Op << ": Vector index not constant: " << IdxId << "\n"; 2553 Errors() << Op << ": Vector index not constant: " << IdxId << "\n";
2535 // TODO(kschimpf): We should check that Idx is a constant with 2554 // TODO(kschimpf): We should check that Idx is a constant with
2536 // valid access. However, we currently don't store constant 2555 // valid access. However, we currently don't store constant
2537 // values, so it can't be tested. 2556 // values, so it can't be tested.
2538 } 2557 }
2539 } 2558 }
2540 2559
2541 /// Checks if block Value is a valid branch target for the current 2560 /// Checks if block Value is a valid branch target for the current
2542 /// function block. If not, generates an appropriate error message. 2561 /// function block. If not, generates an appropriate error message.
2543 void VerifyBranchRange(uint64_t Value) { 2562 void VerifyBranchRange(uint64_t Value) {
2544 if (0 == Value || Value >= ExpectedNumBbs) { 2563 if (0 == Value || Value >= ExpectedNumBbs) {
2545 Errors() << "Branch " << BitcodeId('b', Value) 2564 Errors() << "Branch " << BitcodeId('b', Value)
2546 << " out of range. Not in [1," << ExpectedNumBbs << "]\n"; 2565 << " out of range. Not in [1," << ExpectedNumBbs << "]\n";
2547 } 2566 }
2548 } 2567 }
2568
2569 /// Convert alignment exponent (i.e. power of two (or zero)) to the
2570 /// corresponding alignment to use. If alignment is too large, it generates
2571 /// an error message and returns 0.
2572 unsigned getAlignmentValue(uint64_t Exponent);
2549 }; 2573 };
2550 2574
2551 NaClDisFunctionParser::NaClDisFunctionParser( 2575 NaClDisFunctionParser::NaClDisFunctionParser(
2552 unsigned BlockID, 2576 unsigned BlockID,
2553 NaClDisBlockParser *EnclosingParser) 2577 NaClDisBlockParser *EnclosingParser)
2554 : NaClDisBlockParser(BlockID, EnclosingParser), 2578 : NaClDisBlockParser(BlockID, EnclosingParser),
2555 CurrentBbIndex(-1), 2579 CurrentBbIndex(-1),
2556 ExpectedNumBbs(0), 2580 ExpectedNumBbs(0),
2557 InstIsTerminating(false) { 2581 InstIsTerminating(false) {
2558 Context->ResetLocalCounters(); 2582 Context->ResetLocalCounters();
(...skipping 12 matching lines...) Expand all
2571 2595
2572 // Now install parameters. 2596 // Now install parameters.
2573 for (size_t Index = 0; Index < FcnTy->getFunctionNumParams(); ++Index) { 2597 for (size_t Index = 0; Index < FcnTy->getFunctionNumParams(); ++Index) {
2574 InstallParamType(FcnTy->getFunctionParamType(Index)); 2598 InstallParamType(FcnTy->getFunctionParamType(Index));
2575 } 2599 }
2576 } 2600 }
2577 2601
2578 void NaClDisFunctionParser::PrintBlockHeader() { 2602 void NaClDisFunctionParser::PrintBlockHeader() {
2579 Tokens() << "function" << Space(); 2603 Tokens() << "function" << Space();
2580 BitcodeId FunctionId('f', FcnId); 2604 BitcodeId FunctionId('f', FcnId);
2581 if (!(Context->IsFunctionIntrinsic(FcnId) 2605 bool InvalidSignature = true; // until proven otherwise.
2582 || PNaClABITypeChecker::isValidFunctionType(FcnTy))) { 2606 if (Context->IsFunctionIntrinsic(FcnId))
2607 InvalidSignature = false;
2608 else if (IgnorePNaClABIChecks ||
2609 PNaClABITypeChecker::isValidFunctionType(FcnTy)) {
2610 InvalidSignature = false;
2611 }
2612 if (InvalidSignature) {
2583 Errors() << "Invalid type signature for " 2613 Errors() << "Invalid type signature for "
2584 << BitcodeId('f', FcnId) << ": " << *FcnTy << "\n"; 2614 << BitcodeId('f', FcnId) << ": " << *FcnTy << "\n";
2585 } 2615 }
2586 Tokens() << TokenizeFunctionSignature(FcnTy, &FunctionId) 2616 Tokens() << TokenizeFunctionSignature(FcnTy, &FunctionId)
2587 << Space() << OpenCurly() 2617 << Space() << OpenCurly()
2588 << Space() << Space() << "// BlockID = " << GetBlockID() 2618 << Space() << Space() << "// BlockID = " << GetBlockID()
2589 << Endline(); 2619 << Endline();
2590 } 2620 }
2591 2621
2592 const char *NaClDisFunctionParser::GetBinop(uint32_t Opcode, Type *Ty) { 2622 const char *NaClDisFunctionParser::GetBinop(uint32_t Opcode, Type *Ty) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 return "ult"; 2789 return "ult";
2760 case CmpInst::FCMP_ULE: 2790 case CmpInst::FCMP_ULE:
2761 return "ule"; 2791 return "ule";
2762 case CmpInst::FCMP_UNE: 2792 case CmpInst::FCMP_UNE:
2763 return "une"; 2793 return "une";
2764 case CmpInst::FCMP_TRUE: 2794 case CmpInst::FCMP_TRUE:
2765 return "true"; 2795 return "true";
2766 } 2796 }
2767 } 2797 }
2768 2798
2799 namespace {
2800
2801 static const unsigned MaxAlignmentExponent = 29;
2802 static_assert(
2803 (1u << MaxAlignmentExponent) == Value::MaximumAlignment,
2804 "Inconsistency between Value.MaxAlignment and PNaCl alignment limit");
2805 }
2806
2807 unsigned NaClDisFunctionParser::getAlignmentValue(uint64_t Exponent) {
2808 if (Exponent > MaxAlignmentExponent + 1) {
2809 Errors() << "Alignment can't be greater than 2**" << MaxAlignmentExponent
2810 << ". Found: 2**" << (Exponent - 1) << "\n";
2811 return 0;
2812 }
2813 return (1 << static_cast<unsigned>(Exponent)) >> 1;
2814 }
2815
2769 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) { 2816 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) {
2770 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit()); 2817 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit());
2771 switch (BlockID) { 2818 switch (BlockID) {
2772 case naclbitc::CONSTANTS_BLOCK_ID: { 2819 case naclbitc::CONSTANTS_BLOCK_ID: {
2773 NaClDisConstantsParser Parser(BlockID, this); 2820 NaClDisConstantsParser Parser(BlockID, this);
2774 return Parser.ParseThisBlock(); 2821 return Parser.ParseThisBlock();
2775 } 2822 }
2776 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 2823 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2777 if (!PNaClAllowLocalSymbolTables) break; 2824 if (!PNaClAllowLocalSymbolTables) break;
2778 NaClDisValueSymtabParser Parser(BlockID, this); 2825 NaClDisValueSymtabParser Parser(BlockID, this);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 << "Function switch record expects at least 4 arguments. Found: " 2954 << "Function switch record expects at least 4 arguments. Found: "
2908 << Values.size() << "\n"; 2955 << Values.size() << "\n";
2909 break; 2956 break;
2910 } 2957 }
2911 Type *OpType = GetType(Values[0]); 2958 Type *OpType = GetType(Values[0]);
2912 uint32_t CondId = RelativeToAbsId(Values[1]); 2959 uint32_t CondId = RelativeToAbsId(Values[1]);
2913 Type *CondType = GetValueType(CondId); 2960 Type *CondType = GetValueType(CondId);
2914 if (OpType != CondType) 2961 if (OpType != CondType)
2915 Errors() << "Specified select type " << *OpType << " but found: " 2962 Errors() << "Specified select type " << *OpType << " but found: "
2916 << *CondType << "\n"; 2963 << *CondType << "\n";
2917 if (!PNaClABITypeChecker::isValidSwitchConditionType(CondType)) 2964 if (!IgnorePNaClABIChecks &&
2965 !PNaClABITypeChecker::isValidSwitchConditionType(CondType)) {
2918 Errors() << PNaClABITypeChecker::ExpectedSwitchConditionType(CondType) 2966 Errors() << PNaClABITypeChecker::ExpectedSwitchConditionType(CondType)
2919 << "\n"; 2967 << "\n";
2968 }
2920 uint32_t DefaultBb = Values[2]; 2969 uint32_t DefaultBb = Values[2];
2921 unsigned NumCases = Values[3]; 2970 unsigned NumCases = Values[3];
2922 VerifyBranchRange(DefaultBb); 2971 VerifyBranchRange(DefaultBb);
2923 Tokens() << "switch" << Space() << StartCluster() << StartCluster() 2972 Tokens() << "switch" << Space() << StartCluster() << StartCluster()
2924 << TokenizeType(OpType) << Space() << GetBitcodeId(CondId) 2973 << TokenizeType(OpType) << Space() << GetBitcodeId(CondId)
2925 << FinishCluster() << Space() << "{" << FinishCluster() 2974 << FinishCluster() << Space() << "{" << FinishCluster()
2926 << Endline(); 2975 << Endline();
2927 IncAssemblyIndent(); 2976 IncAssemblyIndent();
2928 Tokens() << StartCluster() << "default" << ":" << Space() 2977 Tokens() << StartCluster() << "default" << ":" << Space()
2929 << FinishCluster() << StartCluster() << "br" << Space() << "label" 2978 << FinishCluster() << StartCluster() << "br" << Space() << "label"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 case naclbitc::FUNC_CODE_INST_ALLOCA: { 3037 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2989 // ALLOCA: [size, align] 3038 // ALLOCA: [size, align]
2990 if (Values.size() != 2) { 3039 if (Values.size() != 2) {
2991 Errors() << "Function alloca record expects 2 arguments. Found: " 3040 Errors() << "Function alloca record expects 2 arguments. Found: "
2992 << Values.size() << "\n"; 3041 << Values.size() << "\n";
2993 break; 3042 break;
2994 } 3043 }
2995 uint32_t SizeOp = RelativeToAbsId(Values[0]); 3044 uint32_t SizeOp = RelativeToAbsId(Values[0]);
2996 Type* SizeType = GetValueType(SizeOp); 3045 Type* SizeType = GetValueType(SizeOp);
2997 BitcodeId SizeId(GetBitcodeId(SizeOp)); 3046 BitcodeId SizeId(GetBitcodeId(SizeOp));
2998 uint64_t Alignment = (1 << Values[1]) >> 1; 3047 unsigned Alignment = getAlignmentValue(Values[1]);
2999 if (!PNaClABIProps::isAllocaSizeType(SizeType)) 3048 if (!IgnorePNaClABIChecks && !PNaClABIProps::isAllocaSizeType(SizeType))
3000 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n"; 3049 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n";
3001 // TODO(kschimpf) Are there any constraints on alignment? 3050 // TODO(kschimpf) Are there any constraints on alignment?
3002 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() 3051 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3003 << "alloca" << Space() << "i8" << Comma() << FinishCluster() 3052 << "alloca" << Space() << "i8" << Comma() << FinishCluster()
3004 << Space() << StartCluster() << TokenizeType(SizeType) << Space() 3053 << Space() << StartCluster() << TokenizeType(SizeType) << Space()
3005 << SizeId << Comma() << FinishCluster() << Space() 3054 << SizeId << Comma() << FinishCluster() << Space()
3006 << StartCluster() <<"align" << Space() << Alignment << Semicolon() 3055 << StartCluster() <<"align" << Space() << Alignment << Semicolon()
3007 << FinishCluster(); 3056 << FinishCluster();
3008 InstallInstType(GetPointerType()); 3057 InstallInstType(GetPointerType());
3009 break; 3058 break;
3010 } 3059 }
3011 case naclbitc::FUNC_CODE_INST_LOAD: { 3060 case naclbitc::FUNC_CODE_INST_LOAD: {
3012 // LOAD: [op, align, ty] 3061 // LOAD: [op, align, ty]
3013 if (Values.size() != 3) { 3062 if (Values.size() != 3) {
3014 Errors() << "Function load record expects 3 arguments. Found: " 3063 Errors() << "Function load record expects 3 arguments. Found: "
3015 << Values.size() << "\n"; 3064 << Values.size() << "\n";
3016 break; 3065 break;
3017 } 3066 }
3018 uint64_t Alignment = (1 << Values[1]) >> 1; 3067 unsigned Alignment = getAlignmentValue(Values[1]);
3019 Type *LoadType = GetType(Values[2]); 3068 Type *LoadType = GetType(Values[2]);
3020 VerifyScalarOrVectorOp("load", LoadType); 3069 VerifyScalarOrVectorOp("load", LoadType);
3021 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment); 3070 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment);
3022 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() 3071 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3023 << "load" << Space() << TokenizeType(LoadType) << "*" << Space() 3072 << "load" << Space() << TokenizeType(LoadType) << "*" << Space()
3024 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() 3073 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3025 << FinishCluster() << Space() << StartCluster() 3074 << FinishCluster() << Space() << StartCluster()
3026 << "align" << Space() << Alignment << Semicolon() 3075 << "align" << Space() << Alignment << Semicolon()
3027 << FinishCluster(); 3076 << FinishCluster();
3028 InstallInstType(LoadType); 3077 InstallInstType(LoadType);
3029 break; 3078 break;
3030 } 3079 }
3031 case naclbitc::FUNC_CODE_INST_STORE: { 3080 case naclbitc::FUNC_CODE_INST_STORE: {
3032 // STORE: [ptr, val, align] 3081 // STORE: [ptr, val, align]
3033 if (Values.size() != 3) { 3082 if (Values.size() != 3) {
3034 Errors() << "Function store record expects 3 arguments. Found: " 3083 Errors() << "Function store record expects 3 arguments. Found: "
3035 << Values.size() << "\n"; 3084 << Values.size() << "\n";
3036 break; 3085 break;
3037 } 3086 }
3038 uint64_t Alignment = (1 << Values[2]) >> 1; 3087 unsigned Alignment = getAlignmentValue(Values[2]);
3039 uint32_t Val = RelativeToAbsId(Values[1]); 3088 uint32_t Val = RelativeToAbsId(Values[1]);
3040 Type *ValType = GetValueType(Val); 3089 Type *ValType = GetValueType(Val);
3041 VerifyScalarOrVectorOp("store", ValType); 3090 VerifyScalarOrVectorOp("store", ValType);
3042 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment); 3091 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment);
3043 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType) 3092 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType)
3044 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster() 3093 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster()
3045 << Space() << StartCluster() << TokenizeType(ValType) << "*" 3094 << Space() << StartCluster() << TokenizeType(ValType) << "*"
3046 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() 3095 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3047 << FinishCluster() << Space() << StartCluster() << "align" 3096 << FinishCluster() << Space() << StartCluster() << "align"
3048 << Space() << Alignment << Semicolon() << FinishCluster(); 3097 << Space() << Alignment << Semicolon() << FinishCluster();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 Errors() << "Call indirect record expects at least 3 arguments. Found: " 3228 Errors() << "Call indirect record expects at least 3 arguments. Found: "
3180 << Values.size() << "\n"; 3229 << Values.size() << "\n";
3181 break; 3230 break;
3182 } 3231 }
3183 } 3232 }
3184 unsigned IsTailCall = (Values[0] & 0x1); 3233 unsigned IsTailCall = (Values[0] & 0x1);
3185 CallingConv::ID CallingConv; 3234 CallingConv::ID CallingConv;
3186 uint32_t FcnId = RelativeToAbsId(Values[1]); 3235 uint32_t FcnId = RelativeToAbsId(Values[1]);
3187 if (!naclbitc::DecodeCallingConv(Values[0]>>1, CallingConv)) 3236 if (!naclbitc::DecodeCallingConv(Values[0]>>1, CallingConv))
3188 Errors() << "Call unknown calling convention:" << (Values[0]>>1) << "\n"; 3237 Errors() << "Call unknown calling convention:" << (Values[0]>>1) << "\n";
3189 if (!PNaClABIProps::isValidCallingConv(CallingConv)) { 3238 if (!IgnorePNaClABIChecks &&
3239 !PNaClABIProps::isValidCallingConv(CallingConv)) {
3190 Errors() << "Call uses disallowed calling convention: " 3240 Errors() << "Call uses disallowed calling convention: "
3191 << PNaClABIProps::CallingConvName(CallingConv) << "(" 3241 << PNaClABIProps::CallingConvName(CallingConv) << "("
3192 << CallingConv << ")\n"; 3242 << CallingConv << ")\n";
3193 } 3243 }
3194 FunctionType *FcnType = 0; 3244 FunctionType *FcnType = 0;
3195 Type *ReturnType = 0; 3245 Type *ReturnType = 0;
3196 size_t ArgIndex = 2; 3246 size_t ArgIndex = 2;
3197 // Flag defining if type checking should be done on argument/return 3247 // Flag defining if type checking should be done on argument/return
3198 // types. 3248 // types.
3199 bool CheckArgRetTypes = true; 3249 bool CheckArgRetTypes = true;
(...skipping 13 matching lines...) Expand all
3213 } else { 3263 } else {
3214 ReturnType = GetType(Values[2]); 3264 ReturnType = GetType(Values[2]);
3215 ArgIndex = 3; 3265 ArgIndex = 3;
3216 } 3266 }
3217 if (!ReturnType->isVoidTy()) { 3267 if (!ReturnType->isVoidTy()) {
3218 Tokens() << NextInstId() << Space() << "=" << Space(); 3268 Tokens() << NextInstId() << Space() << "=" << Space();
3219 } 3269 }
3220 if (IsTailCall) { 3270 if (IsTailCall) {
3221 Tokens() << "tail" << Space(); 3271 Tokens() << "tail" << Space();
3222 } 3272 }
3223 if (CheckArgRetTypes && !PNaClABITypeChecker::isValidParamType(ReturnType)) 3273 if (CheckArgRetTypes &&
3274 !IgnorePNaClABIChecks &&
3275 !PNaClABITypeChecker::isValidParamType(ReturnType)) {
3224 Errors() << "Invalid return type: " << *ReturnType << "\n"; 3276 Errors() << "Invalid return type: " << *ReturnType << "\n";
3277 }
3225 Tokens() << "call" << Space(); 3278 Tokens() << "call" << Space();
3226 if (CallingConv != CallingConv::C) { 3279 if (CallingConv != CallingConv::C) {
3227 Tokens() << PNaClABIProps::CallingConvName(CallingConv) << Space(); 3280 Tokens() << PNaClABIProps::CallingConvName(CallingConv) << Space();
3228 } 3281 }
3229 Tokens() << TokenizeType(ReturnType) << Space() 3282 Tokens() << TokenizeType(ReturnType) << Space()
3230 << StartCluster() << GetBitcodeId(FcnId) << OpenParen() 3283 << StartCluster() << GetBitcodeId(FcnId) << OpenParen()
3231 << StartCluster(); 3284 << StartCluster();
3232 unsigned ParamIndex = 0; 3285 unsigned ParamIndex = 0;
3233 unsigned NumParams = Values.size() + 1 - ArgIndex; 3286 unsigned NumParams = Values.size() + 1 - ArgIndex;
3234 for (size_t i = ArgIndex; i < Values.size(); ++i, ++ParamIndex) { 3287 for (size_t i = ArgIndex; i < Values.size(); ++i, ++ParamIndex) {
3235 uint32_t ParamId = RelativeToAbsId(Values[i]); 3288 uint32_t ParamId = RelativeToAbsId(Values[i]);
3236 Type *ParamType = GetValueType(ParamId); 3289 Type *ParamType = GetValueType(ParamId);
3237 if (CheckArgRetTypes && !PNaClABITypeChecker::isValidParamType(ParamType)) 3290 if (CheckArgRetTypes &&
3291 !IgnorePNaClABIChecks &&
3292 !PNaClABITypeChecker::isValidParamType(ParamType)) {
3238 Errors() << "invalid type for parameter " << i << ": " 3293 Errors() << "invalid type for parameter " << i << ": "
3239 << *ParamType << "\n"; 3294 << *ParamType << "\n";
3295 }
3240 if (FcnType) { 3296 if (FcnType) {
3241 if (ParamIndex < FcnType->getNumParams()) { 3297 if (ParamIndex < FcnType->getNumParams()) {
3242 Type *ExpectedType = FcnType->getParamType(ParamIndex); 3298 Type *ExpectedType = FcnType->getParamType(ParamIndex);
3243 if (ParamType != ExpectedType) { 3299 if (ParamType != ExpectedType) {
3244 Warnings() << "Parameter " << (ParamIndex + 1) << " mismatch: " 3300 Warnings() << "Parameter " << (ParamIndex + 1) << " mismatch: "
3245 << *ParamType << " and " << *ExpectedType << "\n"; 3301 << *ParamType << " and " << *ExpectedType << "\n";
3246 } 3302 }
3247 } 3303 }
3248 else if (ParamIndex == FcnType->getNumParams()) { 3304 else if (ParamIndex == FcnType->getNumParams()) {
3249 Warnings() << "Call expects " << FcnType->getNumParams() 3305 Warnings() << "Call expects " << FcnType->getNumParams()
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3309 // was checked in method ProcessRecord. 3365 // was checked in method ProcessRecord.
3310 // Note: If the function was defined, the type was checked in 3366 // Note: If the function was defined, the type was checked in
3311 // NaClDisFunctionParser::PrintBlockHeader. 3367 // NaClDisFunctionParser::PrintBlockHeader.
3312 if (Context->HasDefinedFunctionIndex(NextFcnDefinedId) 3368 if (Context->HasDefinedFunctionIndex(NextFcnDefinedId)
3313 && i == Context->GetDefinedFunctionIndex(NextFcnDefinedId)) { 3369 && i == Context->GetDefinedFunctionIndex(NextFcnDefinedId)) {
3314 ++NextFcnDefinedId; 3370 ++NextFcnDefinedId;
3315 continue; 3371 continue;
3316 } 3372 }
3317 if (FunctionType *FcnTy = dyn_cast<FunctionType>(GetFunctionValueType(i))) { 3373 if (FunctionType *FcnTy = dyn_cast<FunctionType>(GetFunctionValueType(i))) {
3318 if (!Context->IsFunctionIntrinsic(i) && 3374 if (!Context->IsFunctionIntrinsic(i) &&
3375 !IgnorePNaClABIChecks &&
3319 !PNaClABITypeChecker::isValidFunctionType(FcnTy)) { 3376 !PNaClABITypeChecker::isValidFunctionType(FcnTy)) {
3320 Context->SetRecordAddressToFunctionIdAddress(i); 3377 Context->SetRecordAddressToFunctionIdAddress(i);
3321 Errors() << "Invalid type signature for " 3378 Errors() << "Invalid type signature for "
3322 << BitcodeId('f', i) << ": " << *FcnTy << "\n"; 3379 << BitcodeId('f', i) << ": " << *FcnTy << "\n";
3323 } 3380 }
3324 } 3381 }
3325 } 3382 }
3326 } 3383 }
3327 3384
3328 bool NaClDisModuleParser::ParseBlock(unsigned BlockID) { 3385 bool NaClDisModuleParser::ParseBlock(unsigned BlockID) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 } 3439 }
3383 bool IsProto = (Values[2] != 0); 3440 bool IsProto = (Values[2] != 0);
3384 Tokens() << StartCluster() << (IsProto ? "declare" : "define"); 3441 Tokens() << StartCluster() << (IsProto ? "declare" : "define");
3385 uint32_t FcnId = GetNumFunctions(); 3442 uint32_t FcnId = GetNumFunctions();
3386 BitcodeId FcnName('f', FcnId); 3443 BitcodeId FcnName('f', FcnId);
3387 std::string FcnStrName(FcnName.GetName()); 3444 std::string FcnStrName(FcnName.GetName());
3388 GlobalValue::LinkageTypes Linkage; 3445 GlobalValue::LinkageTypes Linkage;
3389 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { 3446 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3390 Errors() << "Unknown linkage value: " << Values[3] << "\n"; 3447 Errors() << "Unknown linkage value: " << Values[3] << "\n";
3391 } else { 3448 } else {
3392 if (!PNaClABIProps::isValidGlobalLinkage(Linkage)) 3449 if (!IgnorePNaClABIChecks &&
3450 !PNaClABIProps::isValidGlobalLinkage(Linkage)) {
3393 Errors() << "Disallowed linkage type: " 3451 Errors() << "Disallowed linkage type: "
3394 << PNaClABIProps::LinkageName(Linkage) << "\n"; 3452 << PNaClABIProps::LinkageName(Linkage) << "\n";
3453 }
3395 Tokens() << Space() << PNaClABIProps::LinkageName(Linkage); 3454 Tokens() << Space() << PNaClABIProps::LinkageName(Linkage);
3396 } 3455 }
3397 CallingConv::ID CallingConv; 3456 CallingConv::ID CallingConv;
3398 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { 3457 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3399 Errors() << "Unknown calling convention value: " << Values[1] << "\n"; 3458 Errors() << "Unknown calling convention value: " << Values[1] << "\n";
3400 } else if (PNaClABIProps::isValidCallingConv(CallingConv)) { 3459 } else if (PNaClABIProps::isValidCallingConv(CallingConv)) {
3401 if (CallingConv != CallingConv::C) { 3460 if (CallingConv != CallingConv::C) {
3402 Tokens() << Space() << PNaClABIProps::CallingConvName(CallingConv); 3461 Tokens() << Space() << PNaClABIProps::CallingConvName(CallingConv);
3403 } 3462 }
3404 } else { 3463 } else {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3515 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:" 3574 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:"
3516 << NumBlocksRead << "\n"; 3575 << NumBlocksRead << "\n";
3517 ErrorsFound = true; 3576 ErrorsFound = true;
3518 } 3577 }
3519 3578
3520 ObjDump.Flush(); 3579 ObjDump.Flush();
3521 return ErrorsFound || Parser.GetNumErrors() > 0; 3580 return ErrorsFound || Parser.GetNumErrors() > 0;
3522 } 3581 }
3523 3582
3524 } 3583 }
OLDNEW
« no previous file with comments | « no previous file | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698