diff --git a/build/autoconf/sanitize.m4 b/build/autoconf/sanitize.m4 index 3193d5c624..4f038ccb6f 100644 --- a/build/autoconf/sanitize.m4 +++ b/build/autoconf/sanitize.m4 @@ -13,7 +13,7 @@ MOZ_ARG_ENABLE_BOOL(address-sanitizer, MOZ_ASAN= ) if test -n "$MOZ_ASAN"; then MOZ_LLVM_HACKS=1 - if test -n "$CLANG_CL"; then + if test "$OS_ARCH" = "WINNT"; then # Look for the ASan runtime binary if test "$CPU_ARCH" = "x86_64"; then MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-x86_64.dll @@ -27,14 +27,14 @@ if test -n "$MOZ_ASAN"; then fi AC_SUBST(MOZ_CLANG_RT_ASAN_LIB_PATH) # Suppressing errors in recompiled code. - if test "$OS_ARCH" = "WINNT"; then + if test -n "$CLANG_CL"; then CFLAGS="-fsanitize-blacklist=$_topsrcdir/build/sanitizers/asan_blacklist_win.txt $CFLAGS" CXXFLAGS="-fsanitize-blacklist=$_topsrcdir/build/sanitizers/asan_blacklist_win.txt $CXXFLAGS" fi fi CFLAGS="-fsanitize=address $CFLAGS" CXXFLAGS="-fsanitize=address $CXXFLAGS" - if test -z "$CLANG_CL"; then + if test "$OS_ARCH" != "WINNT"; then LDFLAGS="-fsanitize=address $LDFLAGS" fi AC_DEFINE(MOZ_ASAN) @@ -80,6 +80,40 @@ if test -n "$MOZ_TSAN"; then fi AC_SUBST(MOZ_TSAN) +dnl ======================================================== +dnl = Use Leak Sanitizer +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(leak-sanitizer, +[ --enable-leak-sanitizer Enable Leak Sanitizer (default=no)], + MOZ_LSAN=1, + MOZ_LSAN= ) +if test -n "$MOZ_LSAN"; then + MOZ_LLVM_HACKS=1 + LDFLAGS="-fsanitize=leak $LDFLAGS" + AC_DEFINE(MOZ_LSAN) + MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer) +fi +AC_SUBST(MOZ_LSAN) + +dnl ======================================================== +dnl = Use Undefined Behavior Sanitizer +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(undefined-sanitizer, +[ --enable-undefined-sanitizer Enable Undefined Behavior Sanitizer (default=no)], + MOZ_UBSAN=1, + MOZ_UBSAN= ) +if test -n "$MOZ_UBSAN"; then + MOZ_LLVM_HACKS=1 + CFLAGS="-fsanitize=undefined $CFLAGS" + CXXFLAGS="-fsanitize=undefined $CXXFLAGS" + if test -z "$CLANG_CL"; then + LDFLAGS="-fsanitize=undefined $LDFLAGS" + fi + AC_DEFINE(MOZ_UBSAN) + MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer) +fi +AC_SUBST(MOZ_UBSAN) + # The LLVM symbolizer is used by all sanitizers AC_SUBST(LLVM_SYMBOLIZER) diff --git a/build/moz.build b/build/moz.build index 4d205f93a2..85f97aebac 100644 --- a/build/moz.build +++ b/build/moz.build @@ -64,9 +64,11 @@ FINAL_TARGET_FILES += ['/.gdbinit'] FINAL_TARGET_PP_FILES += ['.gdbinit_python.in'] OBJDIR_FILES += ['!/dist/bin/.gdbinit_python'] -# Install the clang-cl runtime library for ASAN next to the binaries we produce. -if CONFIG['MOZ_ASAN'] and CONFIG['CLANG_CL']: - FINAL_TARGET_FILES += ['%' + CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']] +# Install the clang runtime library for ASAN next to the binaries we produce. +if CONFIG['MOZ_ASAN'] and CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']: + FINAL_TARGET_FILES += [CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']] +if CONFIG['LLVM_SYMBOLIZER']: + FINAL_TARGET_FILES += ['/' + CONFIG['LLVM_SYMBOLIZER']] if CONFIG['MOZ_APP_BASENAME']: FINAL_TARGET_PP_FILES += ['application.ini'] diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index 527e3afd50..9b611d429b 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -196,6 +196,7 @@ def old_configure_options(*options): '--enable-ios-target', '--enable-jitspew', '--enable-js-lto', + '--enable-leak-sanitizer', '--enable-libjpeg-turbo', '--enable-libproxy', '--enable-llvm-hacks', @@ -246,6 +247,7 @@ def old_configure_options(*options): '--enable-thread-sanitizer', '--enable-trace-logging', '--enable-ui-locale', + '--enable-undefined-sanitizer', '--enable-universalchardet', '--enable-updater', '--enable-url-classifier', diff --git a/build/unix/moz.build b/build/unix/moz.build index 88c933295c..cd455b7a4d 100644 --- a/build/unix/moz.build +++ b/build/unix/moz.build @@ -9,9 +9,6 @@ if CONFIG['MOZ_LIBSTDCXX_TARGET_VERSION'] or CONFIG['MOZ_LIBSTDCXX_HOST_VERSION' if CONFIG['USE_ELF_HACK']: DIRS += ['elfhack'] -if CONFIG['LLVM_SYMBOLIZER']: - FINAL_TARGET_FILES += ['/' + CONFIG['LLVM_SYMBOLIZER']] - SDK_FILES.bin += [ 'run-mozilla.sh', ] diff --git a/js/src/vm/Stopwatch.cpp b/js/src/vm/Stopwatch.cpp index 46841b27f8..2c267d446d 100644 --- a/js/src/vm/Stopwatch.cpp +++ b/js/src/vm/Stopwatch.cpp @@ -409,7 +409,8 @@ AutoStopwatch::getCycles(JSRuntime* runtime) const cpuid_t inline AutoStopwatch::getCPU() const { -#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA +// Temporary disable untested code path. Issue #2255 +#if 0 //defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA PROCESSOR_NUMBER proc; GetCurrentProcessorNumberEx(&proc); @@ -423,7 +424,8 @@ AutoStopwatch::getCPU() const bool inline AutoStopwatch::isSameCPU(const cpuid_t& a, const cpuid_t& b) const { -#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA +// Temporary disable untested code path. Issue #2255 +#if 0 //defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA return a.group_ == b.group_ && a.number_ == b.number_; #else return true; diff --git a/js/src/vm/Stopwatch.h b/js/src/vm/Stopwatch.h index 5658a05726..c7b4e3457f 100644 --- a/js/src/vm/Stopwatch.h +++ b/js/src/vm/Stopwatch.h @@ -271,7 +271,8 @@ struct PerformanceMonitoring { uint64_t highestTimestampCounter_; }; -#if WINVER >= 0x0600 +// Temporary disable untested code path. Issue #2255 +#if 0 // WINVER >= 0x0600 struct cpuid_t { WORD group_; BYTE number_; diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index b9485c0c0c..3ab62ac11a 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -226,6 +226,7 @@ ReflowInput::ReflowInput( mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false; mFlags.mIsColumnBalancing = false; mFlags.mIsFlexContainerMeasuringHeight = false; + mFlags.mTreatBSizeAsIndefinite = false; mFlags.mDummyParentReflowInput = false; mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP); mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE); @@ -2045,6 +2046,10 @@ ReflowInput::ComputeContainingBlockRectangle( WritingMode wm = aContainingBlockRI->GetWritingMode(); + if (aContainingBlockRI->mFlags.mTreatBSizeAsIndefinite) { + cbSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; + } + // mFrameType for abs-pos tables is NS_CSS_FRAME_TYPE_BLOCK, so we need to // special case them here. if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE || @@ -2081,12 +2086,13 @@ ReflowInput::ComputeContainingBlockRectangle( } } else { // an element in quirks mode gets a containing block based on looking for a - // parent with a non-auto height if the element has a percent height - // Note: We don't emulate this quirk for percents in calc() or in - // vertical writing modes. + // parent with a non-auto height if the element has a percent height. + // Note: We don't emulate this quirk for percents in calc(), or in vertical + // writing modes, or if the containing block is a flex or grid item. if (!wm.IsVertical() && NS_AUTOHEIGHT == cbSize.BSize(wm)) { if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() && + !aContainingBlockRI->mFrame->IsFlexOrGridItem() && mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent) { cbSize.BSize(wm) = CalcQuirkContainingBlockHeight(aContainingBlockRI); } @@ -2222,7 +2228,8 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext, // in quirks mode, get the cb height using the special quirk method if (!wm.IsVertical() && eCompatibility_NavQuirks == aPresContext->CompatibilityMode()) { - if (!IS_TABLE_CELL(fType)) { + if (!IS_TABLE_CELL(fType) && + !cbrs->mFrame->IsFlexOrGridItem()) { cbSize.BSize(wm) = CalcQuirkContainingBlockHeight(cbrs); if (cbSize.BSize(wm) == NS_AUTOHEIGHT) { blockSizeUnit = eStyleUnit_Auto; diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h index a70549d8eb..52c90e6eeb 100644 --- a/layout/generic/ReflowInput.h +++ b/layout/generic/ReflowInput.h @@ -206,6 +206,13 @@ public: uint32_t mIsFlexContainerMeasuringHeight:1; // nsFlexContainerFrame is // reflowing this child to // measure its intrinsic height. + uint32_t mTreatBSizeAsIndefinite:1; // If this flag is set, the BSize of this frame should be considered + // indefinite for the purposes of percent resolution on child frames (we + // should behave as if ComputedBSize() were NS_INTRINSIC_ISIZE when doing + // percent resolution against this.ComputedBSize()). For example: flex + // items may have their ComputedBSize() resolved ahead-of-time by their + // flex container, and yet their BSize might have to be considered + // indefinite per https://drafts.csswg.org/css-flexbox/#definite-sizes uint32_t mDummyParentReflowInput:1; // a "fake" reflow state made // in order to be the parent // of a real one diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 18a0643f14..d60308f424 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -557,6 +557,8 @@ public: return mFlexShrink * mFlexBaseSize; } + bool TreatBSizeAsIndefinite() const { return mTreatBSizeAsIndefinite; } + const AspectRatio IntrinsicRatio() const { return mIntrinsicRatio; } bool HasIntrinsicRatio() const { return !!mIntrinsicRatio; } @@ -799,6 +801,9 @@ protected: // Does this item need to resolve a min-[width|height]:auto (in main-axis). bool mNeedsMinSizeAutoResolution; + // Should we take care to treat this item's resolved BSize as indefinite? + bool mTreatBSizeAsIndefinite; + const WritingMode mWM; // The flex item's writing mode. uint8_t mAlignSelf; // My "align-self" computed value (with "auto" // swapped out for parent"s "align-items" value, @@ -1990,6 +1995,40 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS; } + // Our main-size is considered definite if any of these are true: + // (a) flex container has definite main size. + // (b) flex item has a definite flex basis and is fully inflexible + // (NOTE: We don't actually check "fully inflexible" because webcompat + // may not agree with that restriction...) + // + // Hence, we need to take care to treat the final main-size as *indefinite* + // if none of these conditions are satisfied. + + // The flex item's main size is its BSize, and is considered definite under + // certain conditions laid out for definite flex-item main-sizes in the spec. + if (aAxisTracker.IsMainAxisHorizontal() || + (containerRS->ComputedBSize() != NS_UNCONSTRAINEDSIZE && + !containerRS->mFlags.mTreatBSizeAsIndefinite)) { + // The flex *container* has a definite main-size (either by being + // row-oriented [and using its own inline size which is by definition + // definite, or by being column-oriented and having a definite + // block-size). The spec says this means all of the flex items' + // post-flexing main sizes should *also* be treated as definite. + mTreatBSizeAsIndefinite = false; + } else if (aFlexBaseSize != NS_UNCONSTRAINEDSIZE) { + // The flex item has a definite flex basis, which we'll treat as making + // its main-size definite. + // XXXdholbert Technically the spec requires the flex item to *also* be + // fully inflexible in order to have its size treated as definite in this + // scenario, but no browser implements that additional restriction, so + // it's not clear that this additional requirement would be + // web-compatible... + mTreatBSizeAsIndefinite = false; + } else { + // Otherwise, we have to treat the item's BSize as indefinite. + mTreatBSizeAsIndefinite = true; + } + SetFlexBaseSizeAndMainSize(aFlexBaseSize); CheckForMinSizeAuto(aFlexItemReflowInput, aAxisTracker); @@ -2054,6 +2093,7 @@ FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize, mIsStretched(false), mIsStrut(true), // (this is the constructor for making struts, after all) mNeedsMinSizeAutoResolution(false), + mTreatBSizeAsIndefinite(false), mWM(aContainerWM), mAlignSelf(NS_STYLE_ALIGN_FLEX_START) { @@ -4463,6 +4503,9 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, childReflowInput.SetComputedWidth(item->GetMainSize()); } else { childReflowInput.SetComputedHeight(item->GetMainSize()); + if (item->TreatBSizeAsIndefinite()) { + childReflowInput.mFlags.mTreatBSizeAsIndefinite = true; + } } } @@ -4802,6 +4845,9 @@ nsFlexContainerFrame::ReflowFlexItem(nsPresContext* aPresContext, } else { childReflowInput.SetComputedHeight(aItem.GetMainSize()); didOverrideComputedHeight = true; + if (aItem.TreatBSizeAsIndefinite()) { + childReflowInput.mFlags.mTreatBSizeAsIndefinite = true; + } } // Override reflow state's computed cross-size if either: @@ -4819,6 +4865,10 @@ nsFlexContainerFrame::ReflowFlexItem(nsPresContext* aPresContext, childReflowInput.SetComputedWidth(aItem.GetCrossSize()); didOverrideComputedWidth = true; } else { + // Note that in the above cases we don't need to worry about the BSize + // needing to be treated as indefinite, because this is for cases where + // the block size would always be considered definite (or where its + // definiteness would be irrelevant). childReflowInput.SetComputedHeight(aItem.GetCrossSize()); didOverrideComputedHeight = true; } diff --git a/layout/reftests/bugs/1128354-1-ref.html b/layout/reftests/bugs/1128354-1-ref.html index a559370f22..a90b26e281 100644 --- a/layout/reftests/bugs/1128354-1-ref.html +++ b/layout/reftests/bugs/1128354-1-ref.html @@ -13,10 +13,21 @@ } .flexInnerHoriz { - display: flex; + height: -moz-fit-content; + margin: 0 0 auto 0; background: pink; } - + .height50pct { + height: -moz-fit-content; + margin: 0 0 auto 0; + background: brown; + } + .height0pct { + height: -moz-fit-content; + margin: 0 0 auto 0; + background: yellow; + } + .spacer { background: lightblue; height: 200px; @@ -28,6 +39,8 @@